# Diagram Renderer: Mermaid & Graphviz to SVG, PNG, PDF (`dryboneslabs/diagram-renderer`) Actor

Turn Mermaid or Graphviz (DOT) code into SVG, PNG or PDF files with a hosted link. Batch up to 100 diagrams per run. Built for AI agents, docs pipelines and n8n/Make/Zapier flows. Pay only for diagrams that render.

- **URL**: https://apify.com/dryboneslabs/diagram-renderer.md
- **Developed by:** [Mike Golay](https://apify.com/dryboneslabs) (community)
- **Categories:** Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 diagram rendereds

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

## Diagram Renderer: Mermaid & Graphviz to SVG, PNG, PDF

Turn **Mermaid** or **Graphviz (DOT)** code into clean **SVG, PNG or PDF** files, each with a link you can share. Send one diagram or a batch of up to 100. Diagrams that fail to render are **not charged**, and the parser's error message comes back so you (or your AI agent) can fix the code and retry.

Made for:

- **AI agents and MCP clients.** LLMs write Mermaid well but can't display it. This Actor gives them an image URL.
- **Docs and reporting pipelines** that keep diagrams as code.
- **n8n, Make, Zapier and Apify integrations** that need a picture of a workflow, an architecture, or a data flow.

### What it does

1. You send diagram code, for example a Mermaid `flowchart`, a `sequenceDiagram`, or a Graphviz `digraph { ... }`.
2. The Actor renders it in a locked-down renderer with no network access.
3. Each file is saved to the run's key-value store. You get **one dataset row per diagram** containing the file `url`, `format`, `width`, `height`, `bytes`, and an `errorCode` and `error` if it failed.

**Supported diagram types**

- **Mermaid:** flowchart/graph, sequence, class, state, entity-relationship, Gantt, pie, mindmap, timeline, user journey, Git graph, quadrant, XY chart, Sankey, block, packet, requirement, C4, architecture, kanban, radar, treemap, and the other diagram types Mermaid supports.
- **Graphviz:** the DOT language, with the `dot`, `neato`, `fdp`, `sfdp`, `circo`, `twopi`, `osage` and `patchwork` layout engines.

**Engine auto-detection:** code that starts with `digraph {` or `graph {` (including `strict` and named graphs) is treated as Graphviz. Everything else is treated as Mermaid. You can also set `engine` explicitly.

### Input

#### One diagram

```json
{
  "source": "flowchart LR\n  A[Request] --> B{Cached?}\n  B -->|yes| C[Return]\n  B -->|no| D[Fetch] --> C",
  "format": "png"
}
```

#### A batch of diagrams

Top-level options act as defaults for every item, and each item can override them.

```json
{
  "format": "svg",
  "theme": "neutral",
  "diagrams": [
    { "id": "login-flow", "source": "sequenceDiagram\n  User->>App: Log in\n  App->>API: POST /session\n  API-->>App: 200 OK" },
    { "id": "deps", "source": "digraph { rankdir=LR; app -> api -> db; app -> cache }", "format": "png", "scale": 3 },
    { "id": "schema", "source": "erDiagram\n  CUSTOMER ||--o{ ORDER : places", "format": "pdf" }
  ]
}
```

| Field | Type | Default | Notes |
|---|---|---|---|
| `source` | string | example flowchart | Code for one diagram. Ignored when `diagrams` is set. Max 50,000 characters. |
| `diagrams` | array | — | Up to 100 items. Each item is an object or a plain string (treated as its `source`). |
| `id` (item) | string | position (`1`, `2`, …) | Used in the file name: `diagram-<id>.<format>`. |
| `engine` | `auto` · `mermaid` · `graphviz` | `auto` | |
| `format` | `png` · `svg` · `pdf` | `png` | PDF is one page, sized to the diagram. |
| `theme` | `default` · `neutral` · `dark` · `forest` · `base` | `default` | Mermaid only. |
| `background` | CSS color | white (dark grey for the `dark` theme) | e.g. `transparent`, `#f5f5f5`, `rgb(0,0,0)`. |
| `scale` | 0.5–4 | 2 | PNG pixel density. 2 gives sharp, retina-quality images. |
| `width` | 16–8000 px | natural size | The height follows the aspect ratio. |
| `layout` | `dot` · `neato` · `fdp` · `sfdp` · `circo` · `twopi` · `osage` · `patchwork` | `dot` | Graphviz only. |

### Output

One dataset item per diagram:

```json
{
  "id": "login-flow",
  "index": 0,
  "ok": true,
  "engine": "mermaid",
  "format": "svg",
  "url": "https://api.apify.com/v2/key-value-stores/<storeId>/records/diagram-login-flow.svg",
  "key": "diagram-login-flow.svg",
  "contentType": "image/svg+xml",
  "bytes": 24117,
  "width": 450,
  "height": 297,
  "renderMs": 182,
  "charged": true,
  "errorCode": null,
  "error": null,
  "warnings": []
}
```

A failed diagram looks like this. It is not charged, and the rest of the batch keeps going:

```json
{
  "id": "bad-one",
  "ok": false,
  "url": null,
  "errorCode": "SYNTAX_ERROR",
  "error": "Mermaid: Parse error on line 2:\n...A --> (((\n-------^\nExpecting 'SQS', 'DOUBLECIRCLESTART', ... got 'PS'",
  "charged": false
}
```

**Error codes:** `SYNTAX_ERROR` (fix the diagram code), `INVALID_INPUT` (a bad option value, or a remote image), `LIMIT_EXCEEDED` (input or output too large), `TIMEOUT`, `RENDER_FAILED`, `STORAGE_FAILED`.

The files are in the run's **key-value store** (Storage → Key-value store → Diagrams). A `RUN_SUMMARY` record holds the counts, charges and timings for the run.

#### Use it from the API

Call the synchronous endpoint to get the dataset rows (with file URLs) in a single request:

```bash
curl -X POST "https://api.apify.com/v2/acts/DryBoneslabs~diagram-renderer/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"source": "graph TD; A-->B; B-->C", "format": "png"}'
```

AI agents can also find and call the Actor through the Apify MCP server.

### Pricing

Pay per event. You only pay for diagrams that render successfully.

| Event | Price |
|---|---|
| Diagram rendered (one SVG, PNG or PDF file) | **$0.008** ($8 per 1,000) |
| Actor start | $0.00005 per run per GB of memory (one event at the default 1 GB; Apify's standard start fee) |

- Failed diagrams (syntax errors, invalid options, timeouts) are **not charged**.
- No platform usage fees on top: compute is included in the price.
- **Max cost per run** is respected. When your limit is reached, the Actor stops cleanly after the last paid diagram, and the remaining items are listed as skipped in the run summary.

Example: a batch of 50 PNG diagrams costs 50 × $0.008 = **$0.40** (plus $0.00005 for the start).

### Limits

| Limit | Value |
|---|---|
| Diagrams per run | 100 |
| Source size | 50,000 characters per diagram |
| PNG size | 16 megapixels, 8,000 px per side. Larger diagrams are scaled down automatically, with a warning. |
| Diagram size (PNG/PDF) | 16,000 px per side before scaling |
| File size | 20 MB |
| Time per diagram | 20 s. After 3 timeouts in a run, the remaining items are skipped (not charged). |

### Security and privacy

- **No network access while rendering.** Diagram code cannot fetch URLs, call internal services or load remote images, fonts or stylesheets. Every request from the renderer is blocked.
- Mermaid runs with `securityLevel: "strict"`: HTML in labels is sanitized and click callbacks are disabled. `%%{init}%%` directives cannot change security settings.
- **Links are stripped from output files.** External links, images, scripts and `@import` rules are removed from SVG output, so the files are safe to embed. If a file had any removed, the item's `warnings` say so.
- Graphviz runs as WebAssembly with no access to the file system.
- Your diagram code is not logged or stored anywhere except your own run's storage.

### FAQ

**My Mermaid diagram fails with a syntax error, but it works on the Mermaid website.**
This Actor uses Mermaid 12. Check the `error` text: it shows the line and the token the parser expected. Newer syntax may need a newer Mermaid version than the one you used elsewhere.

**Can I use images or icons from URLs inside diagrams?**
No. The renderer has no internet access, for security. Embed small images as `data:image/png;base64,...` URIs instead.

**Why does my SVG look different in Inkscape, Word or PowerPoint?**
Mermaid flowchart labels use HTML (`foreignObject`), which browsers display perfectly but some desktop apps don't. Use PNG or PDF for Office documents.

**Do theme and background apply to Graphviz?**
`background` does. `theme` is Mermaid-only, so style Graphviz with DOT attributes (`node [style=filled, fillcolor="#e8f0fe"]`).

**How long do files stay available?**
As long as the run's storage is retained under your Apify plan's data retention. Download or copy files you want to keep.

**Is this an official Mermaid or Graphviz product?**
No. This Actor is an independent tool. It is not affiliated with or endorsed by the Mermaid or Graphviz projects. It uses the open-source [Mermaid](https://github.com/mermaid-js/mermaid) (MIT) and [Graphviz](https://graphviz.org) (EPL, via the Apache-2.0 `@hpcc-js/wasm-graphviz` build) libraries.

### Changelog

- **1.0**: First release. Mermaid and Graphviz input; SVG, PNG and PDF output; batches of up to 100 diagrams; pay-per-event pricing.

# Actor input Schema

## `source` (type: `string`):

Mermaid (flowchart, sequence, class, state, ER, gantt, pie, mindmap, timeline, ...) or Graphviz DOT code. Ignored when <b>Batch of diagrams</b> is filled. Max 50,000 characters.

## `diagrams` (type: `array`):

Up to 100 diagrams per run. Each item: <code>{ "source": "...", "id"?: "file-name", "engine"?: "auto|mermaid|graphviz", "format"?: "svg|png|pdf", "theme"?, "background"?, "scale"?, "width"?, "layout"? }</code>. Plain strings are accepted as <code>source</code>. Missing fields use the options below.

## `engine` (type: `string`):

<b>auto</b> detects Graphviz DOT (<code>digraph { ... }</code> / <code>graph { ... }</code>) and treats everything else as Mermaid.

## `format` (type: `string`):

SVG (vector, smallest), PNG (image) or PDF (single page sized to the diagram).

## `theme` (type: `string`):

Mermaid color theme. Ignored for Graphviz (style DOT with its own attributes).

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

CSS color such as <code>white</code>, <code>transparent</code>, <code>#f5f5f5</code> or <code>rgb(0,0,0)</code>. Empty = white (dark grey for the Mermaid dark theme).

## `scale` (type: `number`):

Pixel density for PNG output: 1 = normal, 2 = sharp/retina (default), up to 4. Large diagrams are scaled down automatically to stay under 16 megapixels.

## `width` (type: `integer`):

Optional target width in CSS pixels. The height follows the aspect ratio. Empty = the diagram's natural size.

## `layout` (type: `string`):

Layout algorithm for Graphviz: dot (hierarchical, default), neato/fdp/sfdp (force-directed), circo (circular), twopi (radial), osage, patchwork. Ignored for Mermaid.

## Actor input object example

```json
{
  "source": "flowchart LR\n    A[Agent writes diagram code] --> B{Diagram Renderer}\n    B -->|Mermaid| C[SVG / PNG / PDF]\n    B -->|Graphviz DOT| C\n    C --> D[(Key-value store URL)]",
  "diagrams": [
    {
      "id": "login-flow",
      "source": "sequenceDiagram\n    User->>App: Log in\n    App->>API: POST /session\n    API-->>App: 200 OK\n    App-->>User: Welcome!",
      "format": "svg"
    },
    {
      "id": "deps",
      "engine": "graphviz",
      "source": "digraph { rankdir=LR; app -> api -> db; app -> cache }",
      "format": "png"
    }
  ],
  "engine": "auto",
  "format": "png",
  "theme": "default",
  "scale": 2,
  "layout": "dot"
}
```

# Actor output Schema

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

One item per input diagram: ok, url, format, width, height, bytes, errorCode, error.

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

Rendered SVG/PNG/PDF files.

## `summary` (type: `string`):

JSON with counts, charges and performance metrics.

# 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 = {
    "source": `flowchart LR
    A[Agent writes diagram code] --> B{Diagram Renderer}
    B -->|Mermaid| C[SVG / PNG / PDF]
    B -->|Graphviz DOT| C
    C --> D[(Key-value store URL)]`
};

// Run the Actor and wait for it to finish
const run = await client.actor("dryboneslabs/diagram-renderer").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 = { "source": """flowchart LR
    A[Agent writes diagram code] --> B{Diagram Renderer}
    B -->|Mermaid| C[SVG / PNG / PDF]
    B -->|Graphviz DOT| C
    C --> D[(Key-value store URL)]""" }

# Run the Actor and wait for it to finish
run = client.actor("dryboneslabs/diagram-renderer").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 '{
  "source": "flowchart LR\\n    A[Agent writes diagram code] --> B{Diagram Renderer}\\n    B -->|Mermaid| C[SVG / PNG / PDF]\\n    B -->|Graphviz DOT| C\\n    C --> D[(Key-value store URL)]"
}' |
apify call dryboneslabs/diagram-renderer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dryboneslabs/diagram-renderer"
        }
    }
}
```

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/doMfk1MeVNKom7BEJ/builds/sQPewHxvAl1u5M2vP/openapi.json
