# Bulk Personalized Image & GIF Generator from Lottie Template (`lakadev/lottie-template-bulk-png-gif`) Actor

Returns a personalized PNG and/or GIF for every row of your data, rendered from one Lottie template (Bodymovin JSON or .lottie): dynamic text, colors and images per row, from JSON, a CSV URL or an Apify dataset. Template-based, not AI. No browser, no MP4. $0.005 per image; failed rows are free.

- **URL**: https://apify.com/lakadev/lottie-template-bulk-png-gif.md
- **Developed by:** [Djam](https://apify.com/lakadev) (community)
- **Categories:** Videos, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 image generateds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bulk Personalized Image & GIF Generator from Lottie Template

**Returns a personalized PNG and/or GIF for every row of your data, rendered from one Lottie animation template, in bulk, with no browser and no After Effects.** Each row replaces the **dynamic text**, the **colors** and the **images** of the template. **$0.005 per image**, and nothing for a row that fails. This is template rendering, not AI image generation: you get your own design with your data in it, the same way every time.

Give it a **Lottie template** (Bodymovin JSON exported from After Effects or Lottie Creator, or a `.lottie` file) and your **rows**: a JSON list, the URL of a **CSV** (a Google Sheet export for example), or an **Apify dataset**, such as the output of another Actor. For every row you get a **PNG** (one still frame) and/or a **GIF** (the whole animation), stored in the key-value store, with one dataset row of links.

**Typical uses**

- **Certificates and name badges**: one PNG per attendee from a CSV (name, course, date). PNG only, there is no PDF output.
- **Greeting cards and invitations**: a card per contact, with the name, a message and a color.
- **Social media visuals**: one 1080 x 1080 image per product, city or offer of a catalog, for example from the dataset of a product or Google Maps scraper.
- **A personalized GIF for an e-mailing**: the animation with the name of each recipient, 480 px and light by default.

It is an alternative to template-based image APIs (Bannerbear, Placid, Creatomate) for people who already design in Lottie.

**Not included**: no MP4 or WebM (PNG and GIF only), no PDF, right-to-left and complex scripts (Arabic, Hebrew, Indic, Thai) are refused for free, an embedded SVG image is refused, no font given by URL, at most 1000 rows per run. See Limits.

### Quick start

The input form is prefilled with a small greeting card (a public domain Lottie that is embedded in the form) and three rows. Run it as is: you get three PNG images in under 30 seconds, for $0.015.

```json
{
  "templateJson": { "...": "the Lottie animation, see the form" },
  "rows": [
    {"Title": "Hello Zoé", "Subtitle": "Welcome to the team", "Badge": "#E4572E"},
    {"Title": "Hello Sam", "Subtitle": "Happy birthday", "Badge": "#17BEBB"},
    {"Title": "Hello Bartholomew", "Subtitle": "Thanks for your order", "Badge": "#FFC914"}
  ]
}
```

By default, a key of a row that has the **name of a text layer** replaces its text, the **id of an image asset** (or the name of an image layer) replaces the image with the picture at that URL, and the **name of a shape layer** replaces its fill color (`#RRGGBB` or `#RGB`). Replace the example rows with yours, or empty the list to inspect your template (see Inspection mode). Use `templateUrl` instead of `templateJson` for a template that is online.

One real output row (same template, with a GIF as well; the links are shortened):

```json
{
  "index": 0,
  "id": "#FFC914",
  "status": "ok",
  "error": null,
  "values": {"Title": "Hello Bartholomew", "Subtitle": "Thanks for your order", "Badge": "#FFC914"},
  "png": {"url": "https://api.apify.com/v2/key-value-stores/<id>/records/row-0.png", "width": 1080, "height": 1080, "frame": 59.0, "timeSeconds": 1.967},
  "gif": {"url": "https://api.apify.com/v2/key-value-stores/<id>/records/row-0.gif", "width": 480, "height": 480, "frames": 30, "fps": 15.0, "delayMs": 70},
  "textFit": [{"layer": "Title", "fontScale": 0.604, "overflow": false}, {"layer": "Subtitle", "fontScale": 1.0, "overflow": false}],
  "warnings": [],
  "imagesCharged": 2
}
```

`id` comes from the `idColumn` input (here `Badge`, only to show the field). `textFit` says the title was reduced to 60.4 % of its size to fit the width of the template text. The files are `row-<index>.png` and `row-<index>.gif` in the default key-value store, and the output tab shows the PNG in the `overview` table.

### From a CSV with your own column names

Your spreadsheet columns do not have to be named like the layers of the template. Say a CSV (`csvUrl`) has the header `Name;Offer;Color`: add `mappings` to tell the Actor where each column goes (this run was tested on the greeting card of the form):

```json
{
  "csvUrl": "https://docs.google.com/spreadsheets/d/<sheet id>/export?format=csv",
  "mappings": [
    {"column": "Name", "target": "text", "layer": "Title"},
    {"column": "Offer", "target": "text", "layer": "Subtitle"},
    {"column": "Color", "target": "color", "layer": "Badge"}
  ],
  "idColumn": "Name"
}
```

(Together with `templateJson` or `templateUrl`.) Without `mappings` and with columns that match nothing, the run stops at once, free, and says which columns it read and which layers the template has. A cell with a wrong color (`teal` instead of `#17BEBB`) fails only its row, free, and the message names the column. For a Google Sheet, see the note in Limits.

### Where do I get a template?

- **Design it**: in After Effects, export with the Bodymovin plugin (tick *Glyphs* for your font); or in Lottie Creator. Name the text layers `Title`, `Subtitle` and so on, and a shape layer `Badge`.
- **Start from the example**: the prefilled card of the input form is a public domain (CC0) Lottie with two texts and two colors. Copy it from the form and change it.
- **A Lottie downloaded from a library** usually has no text layers to replace. Run the Actor once with no rows (see Inspection mode): `TEMPLATE_INFO` lists exactly which texts, colors and images can be replaced in it (empty lists mean nothing can). Check the license of the animation before you publish images made from it.

### Use it from an AI agent (MCP)

Through the Apify MCP server, call the Actor with `call-actor`, then read the rows with `get-dataset-items`. The agent has to send the template itself (`templateJson`, up to 5 MB, or `templateUrl`). Keep to 100 rows for PNG or 20 rows for GIF so that the run ends within the 45 seconds of `call-actor`; in our local test 50 PNG rows took 4 seconds. Set `maxTotalChargeUsd` to cap the cost ($0.005 per image, so 50 images are $0.25). Each dataset row is small (status, values, links, no image data), and `status` tells which rows to fix. For a first call with no rows, `TEMPLATE_INFO` tells the agent which keys the rows may use.

```json
{
  "templateUrl": "https://example.com/card.json",
  "rows": [{"Title": "Hello Zoé", "Subtitle": "Welcome", "Badge": "#E4572E"}],
  "png": true,
  "pngSize": 1080
}
```

**From code (HTTP API)**: one call that waits for the run and returns the dataset rows (the 300 s limit of this endpoint applies):

```bash
curl -X POST "https://api.apify.com/v2/acts/lakadev~lottie-template-bulk-png-gif/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"templateUrl": "https://example.com/card.json", "rows": [{"Title": "Hello Zoé"}]}'
```

Each returned row has `png.url` (and `gif.url`): download it with a plain GET.

### Prepare your template

The Actor changes the JSON of the template, so the template must give it handles:

1. **Name your layers** in After Effects (or in the Lottie editor): a text layer named `Title`, a shape layer named `Badge`, an image layer named `Photo`. Names are case sensitive in `mappings`, and case-insensitive in the automatic matching.
2. **Write the longest expected value** as the placeholder text of a text layer. The Actor reduces a longer text to the width of the placeholder (see Text that is too long). Or give `maxWidth` in a mapping.
3. **Embed your font** when you export (the *Glyphs* option of the Bodymovin export, or an embedded font). Otherwise the text is drawn with **DejaVu Sans**, a fallback font: the picture is correct but not in your font. The Actor never downloads fonts. Only the characters that the template font contains can be used (see Unsupported scripts). Fills and strokes drawn inside font glyphs (`chars`) are ignored, because the renderer crashes on them: the text color comes from the text layer, and `TEMPLATE_INFO.warnings` then has `GLYPH_STYLE_IGNORED`.
4. **Embed images** in the file (base64, PNG, JPEG, WebP or GIF; an embedded SVG image is refused). An image that is not embedded is never downloaded and stays empty, unless you replace it with an `image` mapping. It is reported in `TEMPLATE_INFO.warnings`.
5. Keep **replaceable images** at 4 megapixels at most (and 4096 px on a side): the picture of each row is scaled to the size of the asset.

Not supported in a template: expressions and some effects (the engine is [ThorVG](https://www.thorvg.org/), close to lottie-web but not identical to the pixel). To check a template before a bulk run, use the companion Actor [Lottie Animation Preview & Validator](https://apify.com/lakadev/lottie-animation-preview-validator) (`lottie-animation-preview-validator`): it renders key frames and lists the features that other players ignore. This Actor also renders your template once before it starts, and refuses it, for free, if the engine cannot draw it.

### Inspection mode

Run with a template and **no rows** (empty `rows`, no `csvUrl`, no `datasetId`). Nothing is rendered and nothing is billed except the start of the run. The key-value store gets a `TEMPLATE_INFO` record that lists what can be replaced:

```json
{
  "width": 1080, "height": 1080, "frameRate": 30, "durationSeconds": 2.0,
  "texts": [{"layer": "Title", "text": "Hello Name", "font": "Greeting-Regular", "fontSource": "fallback", "box": false}],
  "colors": [{"layer": "Badge", "kind": "shape", "color": "#3366E6"}],
  "images": [{"asset": "photo", "width": 400, "height": 400, "layers": ["Photo"]}],
  "mapping": [],
  "warnings": []
}
```

(Shortened.) `fontSource` is `embedded`, `glyphs` or `fallback`; `box` is true for a text in a box (paragraph text). `colors` lists the shape layers that have a fill, and the solids. The status message says, for example, "Template inspected: 2 text layers, 2 color layers, 0 image assets. See TEMPLATE_INFO; add rows to render." In a normal run, `TEMPLATE_INFO.mapping` shows which column was matched to which element.

### Mappings

With the default (empty `mappings`), columns are matched to template elements by name, in this order, ignoring case and spaces at the ends: text layer names, image asset ids, image layer names, shape layer names that have a fill. The first kind found wins; other columns are ignored. For a CSV the columns are those of the header line; for JSON rows and datasets, the keys of the first 100 rows. If no column matches anything, the run is refused with the list of columns and of template elements.

When your column names differ from the layer names, give `mappings`, a list of objects:

```json
[
  {"column": "name", "target": "text", "layer": "Title", "fit": "shrink", "maxWidth": 900},
  {"column": "brand_color", "target": "color", "layer": "Badge"},
  {"column": "location.city", "target": "text", "layer": "Subtitle"},
  {"column": "photo_url", "target": "image", "asset": "photo", "imageFit": "cover"}
]
```

- `column`: a key of the row. A path with dots follows nested objects (`location.city`) and array positions (`images.0`).
- `target`: `text`, `color` or `image`.
- `layer`: the exact name (`nm`) of the layer, for `text` and `color`. All layers with that name are changed, including those inside precompositions. A color applies to every fill of a shape layer (groups included; gradients and strokes are not changed), to the color of a text layer, or to a solid.
- `asset` or `layer` for `image`: the id of an image asset, or the name of an image layer. The value must be the public URL of a PNG, JPEG, WebP or GIF (first frame). It is scaled to the size of the asset: `imageFit` `cover` (default) fills it and crops, `contain` fits it whole on a transparent background. An image smaller than the asset is enlarged, with the warning `IMAGE_UPSCALED`.
- `fit` and `maxWidth`, for `text` only (see below).

A missing or `null` value leaves the element of the template as it is. An empty string empties a text, and leaves a color or an image as it is. Numbers are written as text (`42`), booleans as `true` or `false`, objects and lists as compact JSON. Text values are normalized (Unicode NFC, line breaks `\n` become a line break of the animation, tabs become spaces) and limited to 1000 characters. Values are never interpreted: no expression, no template syntax, no HTML.

Colors must be `#RRGGBB` or `#RGB`. `red` or `rgb(0,0,0)` give an `invalid_row` (free).

### Text that is too long

By default (`fit: shrink`) the Actor reduces the **font size**, never the text, down to **50 %** of the size of the template. The rule is measured with the rendering engine itself, in the units of the layer:

- **Point text** (the usual case): the reference width is the width of the placeholder text of the template, or `maxWidth` if you give it. A longer value is scaled by `reference / width`. A shorter value keeps its size.
- **Text in a box** (paragraph text with a fixed size): the engine wraps the words in the box, and the Actor takes the largest factor from 1 down to 0.5 for which the height of the wrapped text fits the height of the box.
- If the value does not fit even at 50 %, it is drawn at 50 %, the row stays `ok` and billed, and has the warning `TEXT_OVERFLOW` and `overflow: true` in `textFit`.
- `fit: none` never measures and never changes the size.

`textFit` in each row gives the `fontScale` used per text layer.

### Unsupported scripts

A row is `text_unsupported` (free, no image) when its text contains:

- a character that the **template font** does not have (the `error` lists the first ten as `U+XXXX`, for example "Characters not available in the template font "Brand-Regular": U+6771 U+4EAC"). Without this check, the image would contain empty boxes and you would pay for it;
- a character of a **right-to-left or complex script**: Arabic, Hebrew, Indic scripts, Thai, Khmer and so on. The engine does not shape them (letters would not be joined and the order would be wrong). Emoji in color are not supported either.

Latin, Cyrillic, Greek, accented letters and Vietnamese work with the fallback font. To use another script, embed a font that has it in your template.

### After another Actor

Choose the dataset of another run in the **Apify dataset** field: its items become the rows, read page by page (100 at a time), and the Actor only **reads** that dataset. Through the API or MCP, pass the id of the dataset as the string `datasetId`. Item fields become columns, nested fields with dot paths, for example `location.city` for a Google Maps place or `images.0` for the first image of a product. Only the columns you map are kept in memory.

Use the `idColumn` input to copy a key of each item (a place id, a SKU) into the `id` field of the output row. The output rows are in the same order as the source.

We have not verified that an integration which starts this Actor when another finishes can read the dataset on every account: if a run says that the dataset is not found or not readable, pass the id through the API with your own token.

### Output

- **Dataset**: one row per data row, in order. `status` is `ok` (all requested files written, billed), `invalid_row`, `image_failed`, `text_unsupported` or `render_failed`, all free. `error` is one English sentence that names the column. `values` shows what was applied, also for failed rows, so you can fix the data.
- **Key-value store**: `row-<index>.png`, `row-<index>.gif`, `TEMPLATE_INFO`, and `TEMPLATE_PROGRESS` (the run resumes where it stopped after a migration, with no duplicate and no double billing). To download **all the files as a ZIP**, use the key-value store API: `GET https://api.apify.com/v2/key-value-stores/<store id>/records` (it answers with a ZIP; add `?prefix=row-` to leave out the other records) with your token. The store id is in the links of the rows.
- The PNG is the frame given by `pngFrame` (percent of the duration, 100 = the last frame, 0 = the first), at `pngSize` pixels on the longest side (default: the size of the template, at most 2048). `background` is `transparent` (PNG with alpha) or `#RRGGBB`.
- The GIF covers the whole animation at `gifFps` images per second (5 to 25, default 15), at most 150 images and 30 seconds, `gifSize` pixels on the longest side (64 to 720, default 480), looping forever. A GIF has no alpha: a transparent background becomes white. A longer animation lowers its own frame rate to stay at 150 images. The 15 fps GIF of a 3 second template has 45 images and 70 ms between two images.
- The links are share links: anyone who has a link can open the file. They stay as long as the run's storages exist (storages of runs are deleted after a time that depends on your Apify plan; save what you keep).

### Limits

- 1000 rows per run (`maxRows`); beyond that the status message says "1000 of 2400 rows processed (maxRows)".
- Template: 10 MB by URL, 5 MB inline, 5000 layers, GIF at most 30 s. PNG at most 2048 px, GIF at most 720 px.
- A row may use 1000 characters of text per value. An image to download is 10 MB at most; PNG, WebP and GIF at most 16 megapixels, JPEG 40 megapixels. A download that does not answer within 15 s fails the row (free).
- CSV: UTF-8, 10 MB, 200 columns, comma, semicolon or tab separators, quotes as in RFC 4180. A CSV that is not UTF-8 or has an unclosed quote is refused. **Google Sheets**: the `export?format=csv` link redirects to a Google host whose `robots.txt` this Actor respects, and the answer varies from one host to another; if a run says that a `googleusercontent.com` host disallows the download, run again or use *File > Share > Publish to web > CSV* and give that link. We do not promise that every Google Sheets link works.
- Memory: 1024 MB (default) to 4096 MB. More memory does not make a run faster.
- The rendering of a row has 30 s. After 3 time-outs or 5 crashes of the renderer in one run, the following rows are `render_failed` without rendering. After 5 network failures on one image host, or 20 time-outs in the run, the images that remain are `image_failed` without a request.
- Not included: MP4 and WebM, a font given by URL, scripts that need shaping, colors of strokes and gradients, position and size of layers, Lottie slots and dotLottie themes, file names from a column, more than 1000 rows.

### Pricing

Pay per event: **$0.005 per image** (`image-generated`): one event per file of a row with status `ok`, so a row that gets a PNG and a GIF is $0.01. Plus $0.00005 when the run starts. Failed rows, refused inputs and inspections cost nothing. 100 PNG images are $0.50. You can set a maximum cost per run: the Actor stops before a row that would exceed it, and exits normally with what it has written.

### Networking and personal data

Every URL (template, CSV, images) is checked: http and https only, no credentials, public addresses only (also after each redirect), at most 5 redirects, `robots.txt` read once per site and respected (the user agent is `LakadevLottieBot/1.0 (+https://apify.com/lakadev/lottie-template-bulk-png-gif)`), no cookies, no proxy. A dataset is read with the token of the run, read only.

Rows often contain names. The Actor keeps nothing outside the storages of the run, and does not send your data anywhere except to fetch the URLs you give. The links of the files are share links (see Output); you remain responsible for the processing of the personal data in your rows and for the licenses of your template, fonts and images. No LottieFiles API is used.

### Licenses

The rendering engine is [ThorVG](https://github.com/thorvg/thorvg) (MIT), used through the `thorvg-python` binding (LGPL-2.1, used unmodified, source at https://github.com/laggykiller/thorvg-python). Other components: Pillow, fonttools (MIT, reads the character tables of fonts), DejaVu Sans (fallback font), aiohttp, Protego. The full notices are in `THIRD_PARTY_NOTICES.md`. The example greeting card is dedicated to the public domain (CC0 1.0).

# Actor input Schema

## `templateUrl` (type: `string`):

Public http or https URL of a Lottie template: a Bodymovin .json file or a .lottie (dotLottie) file, up to 10 MB. Use it for a template that is already online or larger than 5 MB. If you also fill Template JSON, this URL wins.

## `templateJson` (type: `object`):

Paste the Lottie JSON here, or use templateUrl. Run once without rows to list what can be replaced. The prefilled example is a small greeting card (public domain, CC0): replace it with your own template.

## `rows` (type: `array`):

One object per image. Keys are column names: by default, a key that equals a text layer name replaces its text, an image asset id replaces the image, a shape layer name replaces its fill color (#RRGGBB). For MCP calls, keep to 100 rows for PNG or 20 rows for GIF so results arrive within 45 s. Replace the example rows with yours, or empty the list to inspect your template. Ignored when csvUrl or datasetId is set.

## `csvUrl` (type: `string`):

Public URL of a CSV file (UTF-8, header line, comma, semicolon or tab separated, up to 10 MB), for example a published Google Sheet. Use it instead of rows when your data is a spreadsheet. If set, rows is ignored.

## `datasetId` (type: `string`):

A dataset of your Apify account whose items become the rows, for example the output of another Actor. This Actor only reads it and never writes to it. If set, rows is ignored. Through the API, pass the dataset id as a string.

## `mappings` (type: `array`):

Leave empty to match columns to template elements by name. Otherwise a list of {"column", "target": "text"|"color"|"image", "layer" (text and color) or "asset" or "layer" (image), "fit": "shrink"|"none", "maxWidth", "imageFit": "cover"|"contain"}. Use it when your column names differ from the layer names. Column names may be paths such as location.city.

## `idColumn` (type: `string`):

Optional column whose value is copied to the id field of each output row, to match results with your data (for example a SKU).

## `png` (type: `boolean`):

Default true. Produce one PNG per row (one still frame of the template). At least one of png and gif must be on.

## `pngFrame` (type: `integer`):

Which moment of the animation the PNG shows, from 0 to 100 percent of its duration. 100 (default) is the last frame, where texts have finished moving in. Use 0 for the first frame.

## `pngSize` (type: `integer`):

Longest side of the PNG, from 64 to 2048 pixels. Leave empty to use the longest side of the template (limited to 2048).

## `gif` (type: `boolean`):

Also produce one GIF per row (the whole animation, at most 30 s and 150 images). Costs one more image per row. Off by default.

## `gifSize` (type: `integer`):

Longest side of the GIF, from 64 to 720 pixels. Smaller GIFs are lighter for an e-mail. Only used when gif is on.

## `gifFps` (type: `integer`):

Wanted images per second, from 5 to 25. Long animations are lowered automatically to stay under 150 images. Only used when gif is on.

## `background` (type: `string`):

Background of the PNG: a color as #RRGGBB, or transparent (default) for a PNG with an alpha channel. A GIF has no alpha: it uses white when this is transparent.

## `maxRows` (type: `integer`):

At most this many rows are processed, from 1 to 1000 (default 1000). Set a small number to try your template before running a whole file.

## Actor input object example

```json
{
  "templateJson": {
    "v": "5.7.0",
    "fr": 30,
    "ip": 0,
    "op": 60,
    "w": 1080,
    "h": 1080,
    "nm": "Greeting card",
    "meta": {
      "a": "Lakadev",
      "d": "CC0 1.0 Universal (public domain dedication)",
      "g": "hand-written"
    },
    "fonts": {
      "list": [
        {
          "fName": "Greeting-Regular",
          "fFamily": "Greeting",
          "fStyle": "Regular",
          "ascent": 75
        }
      ]
    },
    "layers": [
      {
        "ty": 5,
        "nm": "Title",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 1,
            "k": [
              {
                "t": 0,
                "s": [
                  -500,
                  430,
                  0
                ],
                "i": {
                  "x": 0.2,
                  "y": 1
                },
                "o": {
                  "x": 0.8,
                  "y": 0
                }
              },
              {
                "t": 15,
                "s": [
                  540,
                  430,
                  0
                ]
              }
            ]
          }
        },
        "t": {
          "d": {
            "k": [
              {
                "t": 0,
                "s": {
                  "f": "Greeting-Regular",
                  "s": 110,
                  "t": "Hello Name",
                  "fc": [
                    1,
                    1,
                    1
                  ],
                  "j": 2,
                  "tr": 0,
                  "lh": 132,
                  "ls": 0
                }
              }
            ]
          },
          "p": {},
          "m": {
            "g": 1,
            "a": {
              "a": 0,
              "k": [
                0,
                0
              ]
            }
          },
          "a": []
        }
      },
      {
        "ty": 5,
        "nm": "Subtitle",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 0,
            "k": [
              540,
              580,
              0
            ]
          }
        },
        "t": {
          "d": {
            "k": [
              {
                "t": 0,
                "s": {
                  "f": "Greeting-Regular",
                  "s": 56,
                  "t": "Thanks for your order",
                  "fc": [
                    1,
                    1,
                    1
                  ],
                  "j": 2,
                  "tr": 0,
                  "lh": 67.2,
                  "ls": 0
                }
              }
            ]
          },
          "p": {},
          "m": {
            "g": 1,
            "a": {
              "a": 0,
              "k": [
                0,
                0
              ]
            }
          },
          "a": []
        }
      },
      {
        "ty": 4,
        "nm": "Badge",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 0,
            "k": [
              540,
              820,
              0
            ]
          }
        },
        "shapes": [
          {
            "ty": "gr",
            "it": [
              {
                "ty": "rc",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    640,
                    120
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                }
              },
              {
                "ty": "fl",
                "c": {
                  "a": 0,
                  "k": [
                    0.2,
                    0.4,
                    0.9,
                    1
                  ]
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              },
              {
                "ty": "tr",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "a": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    100,
                    100
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              }
            ]
          }
        ]
      },
      {
        "ty": 4,
        "nm": "Background",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 0,
            "k": [
              540,
              540,
              0
            ]
          }
        },
        "shapes": [
          {
            "ty": "gr",
            "it": [
              {
                "ty": "rc",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    1080,
                    1080
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                }
              },
              {
                "ty": "fl",
                "c": {
                  "a": 0,
                  "k": [
                    0.12,
                    0.14,
                    0.2,
                    1
                  ]
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              },
              {
                "ty": "tr",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "a": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    100,
                    100
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              }
            ]
          }
        ]
      }
    ]
  },
  "rows": [
    {
      "Title": "Hello Zoé",
      "Subtitle": "Welcome to the team",
      "Badge": "#E4572E"
    },
    {
      "Title": "Hello Sam",
      "Subtitle": "Happy birthday",
      "Badge": "#17BEBB"
    },
    {
      "Title": "Hello Bartholomew",
      "Subtitle": "Thanks for your order",
      "Badge": "#FFC914"
    }
  ],
  "mappings": [],
  "png": true,
  "pngFrame": 100,
  "gif": false,
  "gifSize": 480,
  "gifFps": 15,
  "background": "transparent",
  "maxRows": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

One row per data row, in source order, as JSON items (overview view).

## `files` (type: `string`):

Keys of the files in the default key-value store (row-<index>.png, row-<index>.gif).

## `templateInfo` (type: `string`):

What the template contains (text layers, colors, images, fonts) and the mapping used.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "templateJson": {
        "v": "5.7.0",
        "fr": 30,
        "ip": 0,
        "op": 60,
        "w": 1080,
        "h": 1080,
        "nm": "Greeting card",
        "meta": {
            "a": "Lakadev",
            "d": "CC0 1.0 Universal (public domain dedication)",
            "g": "hand-written"
        },
        "fonts": {
            "list": [
                {
                    "fName": "Greeting-Regular",
                    "fFamily": "Greeting",
                    "fStyle": "Regular",
                    "ascent": 75
                }
            ]
        },
        "layers": [
            {
                "ty": 5,
                "nm": "Title",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100
                    },
                    "r": {
                        "a": 0,
                        "k": 0
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0
                        ]
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100
                        ]
                    },
                    "p": {
                        "a": 1,
                        "k": [
                            {
                                "t": 0,
                                "s": [
                                    -500,
                                    430,
                                    0
                                ],
                                "i": {
                                    "x": 0.2,
                                    "y": 1
                                },
                                "o": {
                                    "x": 0.8,
                                    "y": 0
                                }
                            },
                            {
                                "t": 15,
                                "s": [
                                    540,
                                    430,
                                    0
                                ]
                            }
                        ]
                    }
                },
                "t": {
                    "d": {
                        "k": [
                            {
                                "t": 0,
                                "s": {
                                    "f": "Greeting-Regular",
                                    "s": 110,
                                    "t": "Hello Name",
                                    "fc": [
                                        1,
                                        1,
                                        1
                                    ],
                                    "j": 2,
                                    "tr": 0,
                                    "lh": 132,
                                    "ls": 0
                                }
                            }
                        ]
                    },
                    "p": {},
                    "m": {
                        "g": 1,
                        "a": {
                            "a": 0,
                            "k": [
                                0,
                                0
                            ]
                        }
                    },
                    "a": []
                }
            },
            {
                "ty": 5,
                "nm": "Subtitle",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100
                    },
                    "r": {
                        "a": 0,
                        "k": 0
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0
                        ]
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100
                        ]
                    },
                    "p": {
                        "a": 0,
                        "k": [
                            540,
                            580,
                            0
                        ]
                    }
                },
                "t": {
                    "d": {
                        "k": [
                            {
                                "t": 0,
                                "s": {
                                    "f": "Greeting-Regular",
                                    "s": 56,
                                    "t": "Thanks for your order",
                                    "fc": [
                                        1,
                                        1,
                                        1
                                    ],
                                    "j": 2,
                                    "tr": 0,
                                    "lh": 67.2,
                                    "ls": 0
                                }
                            }
                        ]
                    },
                    "p": {},
                    "m": {
                        "g": 1,
                        "a": {
                            "a": 0,
                            "k": [
                                0,
                                0
                            ]
                        }
                    },
                    "a": []
                }
            },
            {
                "ty": 4,
                "nm": "Badge",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100
                    },
                    "r": {
                        "a": 0,
                        "k": 0
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0
                        ]
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100
                        ]
                    },
                    "p": {
                        "a": 0,
                        "k": [
                            540,
                            820,
                            0
                        ]
                    }
                },
                "shapes": [
                    {
                        "ty": "gr",
                        "it": [
                            {
                                "ty": "rc",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0
                                    ]
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        640,
                                        120
                                    ]
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0
                                }
                            },
                            {
                                "ty": "fl",
                                "c": {
                                    "a": 0,
                                    "k": [
                                        0.2,
                                        0.4,
                                        0.9,
                                        1
                                    ]
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100
                                }
                            },
                            {
                                "ty": "tr",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0
                                    ]
                                },
                                "a": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0
                                    ]
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        100,
                                        100
                                    ]
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100
                                }
                            }
                        ]
                    }
                ]
            },
            {
                "ty": 4,
                "nm": "Background",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100
                    },
                    "r": {
                        "a": 0,
                        "k": 0
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0
                        ]
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100
                        ]
                    },
                    "p": {
                        "a": 0,
                        "k": [
                            540,
                            540,
                            0
                        ]
                    }
                },
                "shapes": [
                    {
                        "ty": "gr",
                        "it": [
                            {
                                "ty": "rc",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0
                                    ]
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        1080,
                                        1080
                                    ]
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0
                                }
                            },
                            {
                                "ty": "fl",
                                "c": {
                                    "a": 0,
                                    "k": [
                                        0.12,
                                        0.14,
                                        0.2,
                                        1
                                    ]
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100
                                }
                            },
                            {
                                "ty": "tr",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0
                                    ]
                                },
                                "a": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0
                                    ]
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        100,
                                        100
                                    ]
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    },
    "rows": [
        {
            "Title": "Hello Zoé",
            "Subtitle": "Welcome to the team",
            "Badge": "#E4572E"
        },
        {
            "Title": "Hello Sam",
            "Subtitle": "Happy birthday",
            "Badge": "#17BEBB"
        },
        {
            "Title": "Hello Bartholomew",
            "Subtitle": "Thanks for your order",
            "Badge": "#FFC914"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lakadev/lottie-template-bulk-png-gif").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "templateJson": {
        "v": "5.7.0",
        "fr": 30,
        "ip": 0,
        "op": 60,
        "w": 1080,
        "h": 1080,
        "nm": "Greeting card",
        "meta": {
            "a": "Lakadev",
            "d": "CC0 1.0 Universal (public domain dedication)",
            "g": "hand-written",
        },
        "fonts": { "list": [{
                    "fName": "Greeting-Regular",
                    "fFamily": "Greeting",
                    "fStyle": "Regular",
                    "ascent": 75,
                }] },
        "layers": [
            {
                "ty": 5,
                "nm": "Title",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100,
                    },
                    "r": {
                        "a": 0,
                        "k": 0,
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0,
                        ],
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100,
                        ],
                    },
                    "p": {
                        "a": 1,
                        "k": [
                            {
                                "t": 0,
                                "s": [
                                    -500,
                                    430,
                                    0,
                                ],
                                "i": {
                                    "x": 0.2,
                                    "y": 1,
                                },
                                "o": {
                                    "x": 0.8,
                                    "y": 0,
                                },
                            },
                            {
                                "t": 15,
                                "s": [
                                    540,
                                    430,
                                    0,
                                ],
                            },
                        ],
                    },
                },
                "t": {
                    "d": { "k": [{
                                "t": 0,
                                "s": {
                                    "f": "Greeting-Regular",
                                    "s": 110,
                                    "t": "Hello Name",
                                    "fc": [
                                        1,
                                        1,
                                        1,
                                    ],
                                    "j": 2,
                                    "tr": 0,
                                    "lh": 132,
                                    "ls": 0,
                                },
                            }] },
                    "p": {},
                    "m": {
                        "g": 1,
                        "a": {
                            "a": 0,
                            "k": [
                                0,
                                0,
                            ],
                        },
                    },
                    "a": [],
                },
            },
            {
                "ty": 5,
                "nm": "Subtitle",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100,
                    },
                    "r": {
                        "a": 0,
                        "k": 0,
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0,
                        ],
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100,
                        ],
                    },
                    "p": {
                        "a": 0,
                        "k": [
                            540,
                            580,
                            0,
                        ],
                    },
                },
                "t": {
                    "d": { "k": [{
                                "t": 0,
                                "s": {
                                    "f": "Greeting-Regular",
                                    "s": 56,
                                    "t": "Thanks for your order",
                                    "fc": [
                                        1,
                                        1,
                                        1,
                                    ],
                                    "j": 2,
                                    "tr": 0,
                                    "lh": 67.2,
                                    "ls": 0,
                                },
                            }] },
                    "p": {},
                    "m": {
                        "g": 1,
                        "a": {
                            "a": 0,
                            "k": [
                                0,
                                0,
                            ],
                        },
                    },
                    "a": [],
                },
            },
            {
                "ty": 4,
                "nm": "Badge",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100,
                    },
                    "r": {
                        "a": 0,
                        "k": 0,
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0,
                        ],
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100,
                        ],
                    },
                    "p": {
                        "a": 0,
                        "k": [
                            540,
                            820,
                            0,
                        ],
                    },
                },
                "shapes": [{
                        "ty": "gr",
                        "it": [
                            {
                                "ty": "rc",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0,
                                    ],
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        640,
                                        120,
                                    ],
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0,
                                },
                            },
                            {
                                "ty": "fl",
                                "c": {
                                    "a": 0,
                                    "k": [
                                        0.2,
                                        0.4,
                                        0.9,
                                        1,
                                    ],
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100,
                                },
                            },
                            {
                                "ty": "tr",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0,
                                    ],
                                },
                                "a": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0,
                                    ],
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        100,
                                        100,
                                    ],
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0,
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100,
                                },
                            },
                        ],
                    }],
            },
            {
                "ty": 4,
                "nm": "Background",
                "ip": 0,
                "op": 60,
                "st": 0,
                "ks": {
                    "o": {
                        "a": 0,
                        "k": 100,
                    },
                    "r": {
                        "a": 0,
                        "k": 0,
                    },
                    "a": {
                        "a": 0,
                        "k": [
                            0,
                            0,
                            0,
                        ],
                    },
                    "s": {
                        "a": 0,
                        "k": [
                            100,
                            100,
                            100,
                        ],
                    },
                    "p": {
                        "a": 0,
                        "k": [
                            540,
                            540,
                            0,
                        ],
                    },
                },
                "shapes": [{
                        "ty": "gr",
                        "it": [
                            {
                                "ty": "rc",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0,
                                    ],
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        1080,
                                        1080,
                                    ],
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0,
                                },
                            },
                            {
                                "ty": "fl",
                                "c": {
                                    "a": 0,
                                    "k": [
                                        0.12,
                                        0.14,
                                        0.2,
                                        1,
                                    ],
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100,
                                },
                            },
                            {
                                "ty": "tr",
                                "p": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0,
                                    ],
                                },
                                "a": {
                                    "a": 0,
                                    "k": [
                                        0,
                                        0,
                                    ],
                                },
                                "s": {
                                    "a": 0,
                                    "k": [
                                        100,
                                        100,
                                    ],
                                },
                                "r": {
                                    "a": 0,
                                    "k": 0,
                                },
                                "o": {
                                    "a": 0,
                                    "k": 100,
                                },
                            },
                        ],
                    }],
            },
        ],
    },
    "rows": [
        {
            "Title": "Hello Zoé",
            "Subtitle": "Welcome to the team",
            "Badge": "#E4572E",
        },
        {
            "Title": "Hello Sam",
            "Subtitle": "Happy birthday",
            "Badge": "#17BEBB",
        },
        {
            "Title": "Hello Bartholomew",
            "Subtitle": "Thanks for your order",
            "Badge": "#FFC914",
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("lakadev/lottie-template-bulk-png-gif").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "templateJson": {
    "v": "5.7.0",
    "fr": 30,
    "ip": 0,
    "op": 60,
    "w": 1080,
    "h": 1080,
    "nm": "Greeting card",
    "meta": {
      "a": "Lakadev",
      "d": "CC0 1.0 Universal (public domain dedication)",
      "g": "hand-written"
    },
    "fonts": {
      "list": [
        {
          "fName": "Greeting-Regular",
          "fFamily": "Greeting",
          "fStyle": "Regular",
          "ascent": 75
        }
      ]
    },
    "layers": [
      {
        "ty": 5,
        "nm": "Title",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 1,
            "k": [
              {
                "t": 0,
                "s": [
                  -500,
                  430,
                  0
                ],
                "i": {
                  "x": 0.2,
                  "y": 1
                },
                "o": {
                  "x": 0.8,
                  "y": 0
                }
              },
              {
                "t": 15,
                "s": [
                  540,
                  430,
                  0
                ]
              }
            ]
          }
        },
        "t": {
          "d": {
            "k": [
              {
                "t": 0,
                "s": {
                  "f": "Greeting-Regular",
                  "s": 110,
                  "t": "Hello Name",
                  "fc": [
                    1,
                    1,
                    1
                  ],
                  "j": 2,
                  "tr": 0,
                  "lh": 132,
                  "ls": 0
                }
              }
            ]
          },
          "p": {},
          "m": {
            "g": 1,
            "a": {
              "a": 0,
              "k": [
                0,
                0
              ]
            }
          },
          "a": []
        }
      },
      {
        "ty": 5,
        "nm": "Subtitle",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 0,
            "k": [
              540,
              580,
              0
            ]
          }
        },
        "t": {
          "d": {
            "k": [
              {
                "t": 0,
                "s": {
                  "f": "Greeting-Regular",
                  "s": 56,
                  "t": "Thanks for your order",
                  "fc": [
                    1,
                    1,
                    1
                  ],
                  "j": 2,
                  "tr": 0,
                  "lh": 67.2,
                  "ls": 0
                }
              }
            ]
          },
          "p": {},
          "m": {
            "g": 1,
            "a": {
              "a": 0,
              "k": [
                0,
                0
              ]
            }
          },
          "a": []
        }
      },
      {
        "ty": 4,
        "nm": "Badge",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 0,
            "k": [
              540,
              820,
              0
            ]
          }
        },
        "shapes": [
          {
            "ty": "gr",
            "it": [
              {
                "ty": "rc",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    640,
                    120
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                }
              },
              {
                "ty": "fl",
                "c": {
                  "a": 0,
                  "k": [
                    0.2,
                    0.4,
                    0.9,
                    1
                  ]
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              },
              {
                "ty": "tr",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "a": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    100,
                    100
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              }
            ]
          }
        ]
      },
      {
        "ty": 4,
        "nm": "Background",
        "ip": 0,
        "op": 60,
        "st": 0,
        "ks": {
          "o": {
            "a": 0,
            "k": 100
          },
          "r": {
            "a": 0,
            "k": 0
          },
          "a": {
            "a": 0,
            "k": [
              0,
              0,
              0
            ]
          },
          "s": {
            "a": 0,
            "k": [
              100,
              100,
              100
            ]
          },
          "p": {
            "a": 0,
            "k": [
              540,
              540,
              0
            ]
          }
        },
        "shapes": [
          {
            "ty": "gr",
            "it": [
              {
                "ty": "rc",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    1080,
                    1080
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                }
              },
              {
                "ty": "fl",
                "c": {
                  "a": 0,
                  "k": [
                    0.12,
                    0.14,
                    0.2,
                    1
                  ]
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              },
              {
                "ty": "tr",
                "p": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "a": {
                  "a": 0,
                  "k": [
                    0,
                    0
                  ]
                },
                "s": {
                  "a": 0,
                  "k": [
                    100,
                    100
                  ]
                },
                "r": {
                  "a": 0,
                  "k": 0
                },
                "o": {
                  "a": 0,
                  "k": 100
                }
              }
            ]
          }
        ]
      }
    ]
  },
  "rows": [
    {
      "Title": "Hello Zoé",
      "Subtitle": "Welcome to the team",
      "Badge": "#E4572E"
    },
    {
      "Title": "Hello Sam",
      "Subtitle": "Happy birthday",
      "Badge": "#17BEBB"
    },
    {
      "Title": "Hello Bartholomew",
      "Subtitle": "Thanks for your order",
      "Badge": "#FFC914"
    }
  ]
}' |
apify call lakadev/lottie-template-bulk-png-gif --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lakadev/lottie-template-bulk-png-gif"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/iuHD55ib8BWIACTDI/builds/MaOYSsXTd9Swc9XGj/openapi.json
