# QR Code & Barcode Generator: Bulk PNG, SVG, PDF Codes (`data-done-right/qr-code-barcode-generator`) Actor

QR code generator and barcode generator for bulk lists: QR (URL, WiFi, vCard, email, SMS, geo, text) and Code 128, Code 39, EAN-13, EAN-8, UPC-A, ISBN-13, ITF to PNG, SVG or PDF. Colors, logo, size, check digits validated, signed download links.

- **URL**: https://apify.com/data-done-right/qr-code-barcode-generator.md
- **Developed by:** [Data Done Right](https://apify.com/data-done-right) (community)
- **Categories:** Developer tools, Automation, Other
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.36 / 1,000 code generateds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## QR Code & Barcode Generator: Bulk PNG, SVG, PDF Codes

This **QR code generator** and **barcode generator** makes hundreds or thousands of codes from a list, one image file per item. Make **bulk QR codes** for URLs, WiFi, contact cards (vCard), email, phone, SMS, locations and plain text, and **generate barcodes** in Code 128, Code 39, EAN-13, EAN-8, UPC-A, ISBN-13 and ITF. Every code is saved as PNG, SVG or PDF and comes with a signed download link. No browser, no login, no API key.

Wrong EAN length or check digit? You get a clear error for that one item (and no charge), and the rest of the list still runs.

### What can this QR code and barcode generator do

- **QR code helpers:** `url`, `text`, `wifi` (join a network by scanning), `vcard` (save a contact), `email` (with subject and body), `phone`, `sms` (with a message), `geo` (a map location).
- **Barcodes:** `code128`, `code39`, `ean13`, `ean8`, `upca`, `isbn13`, `itf`, `itf14`.
- **Check digits handled for you.** Give EAN-13 / EAN-8 / UPC-A / ISBN-13 / ITF-14 without the last digit and it is added (`autoCheckDigit`). Give a full number with a wrong last digit and the error tells you the right one. Code 128 computes its own check character automatically; Code 39 has an optional modulo-43 check character.
- **Look:** foreground and background colors, QR error correction (L, M, Q, H), box size, border, barcode bar width and height, quiet zone, and human-readable text under the bars on or off.
- **Logo in the middle of a QR code:** point `logoUrl` at a PNG, JPG or WebP. Error correction is raised to H automatically so it still scans. The logo is downloaded safely (public addresses only).
- **Output formats:** PNG, SVG (vector, for print) or PDF (one code per page). Set one format for the run, or override it per item.
- **Bulk and safe:** up to 5,000 codes per run, one bad item never stops the run, identical items are not generated twice.

### How to generate QR codes in bulk

1. Open the Input tab and list your codes in **Codes to generate**, one object per code.
2. Choose the **Output format** (PNG, SVG or PDF), colors and error correction.
3. Run it. Each file is stored in the run's key-value store, and the dataset has a signed `url` for each one that works without an API token.

Quick tip: for a plain list of URLs set **Default type** to `url` and give each entry as a simple text value.

### How to generate barcodes in bulk

Use `type` `code128`, `ean13`, `upca` and so on in each entry. Example: `{"type": "ean13", "value": "590123412345"}` creates a valid EAN-13 (check digit 7 is added). Set `moduleWidth` and `barHeight` for the size and `showText` to print the digits.

### Input example

```json
{
  "items": [
    {"type": "url", "value": "https://apify.com"},
    {"type": "code128", "value": "APIFY-0001"},
    {"type": "ean13", "value": "5901234123457"},
    {"type": "wifi", "data": {"ssid": "Cafe Guest", "password": "welcome123", "security": "WPA"}},
    {"type": "vcard", "data": {"firstName": "Ada", "lastName": "Lovelace", "organization": "Analytical Engines", "email": "ada@example.com", "phone": "+15551234567"}},
    {"type": "email", "value": "hello@example.com", "data": {"subject": "Hi"}},
    {"type": "geo", "value": "48.8584,2.2945", "format": "svg", "fileName": "eiffel-tower"}
  ],
  "format": "png",
  "errorCorrection": "Q",
  "foregroundColor": "#000000",
  "backgroundColor": "#ffffff",
  "logoUrl": "https://example.com/logo.png"
}
```

Fields per item: `type`, `value`, `data` (fields for wifi, vcard, email, sms, geo), and optionally `format`, `fileName`, `foregroundColor`, `backgroundColor`. An entry can also be just a text value, which uses **Default type**.

Fields in `data`: wifi `ssid`, `password`, `security` (WPA, WEP, nopass), `hidden`. vcard `firstName`, `lastName`, `name`, `organization`, `title`, `phone`, `mobile`, `email`, `website`, `street`, `city`, `region`, `postalCode`, `country`, `note`. email `to`, `subject`, `body`. sms `number`, `message`. geo `lat`, `lon`.

### Output

One dataset row per item:

```json
{
  "index": 3,
  "value": "5901234123457",
  "type": "ean13",
  "format": "png",
  "fileName": "5901234123457.png",
  "url": "https://api.apify.com/v2/key-value-stores/<storeId>/records/5901234123457-8f2a1c3d4e5f.png?signature=...",
  "bytes": 1403,
  "width": 336,
  "height": 125,
  "encoded": "5901234123457",
  "status": "generated",
  "error": null,
  "note": null
}
```

- `status`: `generated` (charged), `failed` (invalid value, see `error`), or `skipped` (duplicate, `maxItems`, spending limit). Failed and skipped rows are free.
- `encoded` shows exactly what is inside the code: the QR text, or the barcode digits including the check digit.
- `note` explains adjustments, for example "check digit 7 added", "https:// was added" or a low-contrast warning.
- The `SUMMARY` record has the totals. A `NOTES` record appears if something needs your attention (for example the logo could not be loaded).

### How much does it cost to generate QR codes and barcodes

Pay per event: **$0.0017 per code generated** (event `code-generated`, about $1.70 per 1,000 codes), plus the normal Apify platform usage of the run, which is small. Invalid items and skipped duplicates are free. Set a maximum spending limit on your run and it stops cleanly when reached.

### Use cases

- Product labels and inventory: EAN-13, UPC-A and Code 128 barcodes from a spreadsheet of SKUs.
- Marketing: one QR code per campaign URL, per flyer, per event badge or per table.
- Hospitality and offices: WiFi QR codes and contact-card QR codes.
- Books: ISBN-13 barcodes.
- Print-ready vector files: choose SVG or PDF.

### Important: QR codes are static and do not expire

These QR codes encode your data directly (the URL, the WiFi password and so on). They work forever and need no subscription or account, but they cannot be edited or tracked after printing. If you may need to change the destination later, encode a short redirect URL that you control. Make sure the content is right before you print.

### Limits (honest)

- A QR code holds up to about 2,900 bytes of text at level L (about 1,270 at level H); longer text fails with a clear error.
- Barcodes follow the standards: EAN, UPC and ISBN need the right digits, Code 39 only has 43 characters, Code 128 here is ASCII only (up to 80 characters).
- Colors with low contrast, or light-on-dark inverted codes, may not scan. A note is added to the row.
- A logo over about 25% of the code can break scanning. Test one printed code before you print thousands. This Actor does not scan codes back.
- Logo must be a PNG, JPG or WebP at a public address (max 5 MB). SVG logos are not supported. If the logo cannot be loaded, QR items fail with that reason and barcodes still work.
- Images are limited to 12,000 pixels on the longest side. Barcodes are drawn as plain bars (no taller guard bars on EAN/UPC); they scan normally.

### FAQ

**Do these QR codes expire?**
No. A QR code is just your data drawn as squares, so it does not expire and there is no service behind it. The flip side is that it is static: you cannot change where it points after printing.

**Can I add my logo to a QR code?**
Yes, set `logoUrl`. Error correction is raised to H and the logo is placed in the center, 20% wide by default (`logoSizePercent`). Keep it at 25% or less.

**Which barcode type should I use?**
Retail products: EAN-13 (worldwide) or UPC-A (USA/Canada). Books: ISBN-13. Warehouses, internal IDs, text: Code 128. Cartons: ITF-14. Simple uppercase IDs: Code 39.

**Why did my EAN-13 fail?**
It must be 12 digits (the check digit is added) or 13 digits with a correct check digit. The error message tells you the digit it should be.

**What is the difference between PNG, SVG and PDF?**
PNG is a normal picture. SVG is a vector file that stays sharp at any size, best for print and design tools. PDF is a one-page document per code.

**Can I generate QR codes for WiFi or contacts?**
Yes. Use `type` `wifi` or `vcard` with the fields in `data`, as in the input example.

### Related tools

- **Image Compressor & Resizer: Compress Images in Bulk**: shrink the generated PNGs or any other images.
- **PDF Merger & Splitter: Merge, Split, Extract Pages**: combine generated PDF codes into one document.
- **Download Images from URLs: Bulk Image & File Downloader**: download images and files in bulk.

# Actor input Schema

## `items` (type: `array`):

One entry per code. Each entry is an object with type and value, for example {"type": "url", "value": "https://example.com"}. Types: url, text, wifi, vcard, email, phone, sms, geo (QR codes) and code128, code39, ean13, ean8, upca, isbn13, itf, itf14 (barcodes). Structured QR types take their fields in data, for example {"type": "wifi", "data": {"ssid": "Cafe", "password": "secret"}}. Plain text entries use the default type. Optional per entry: format, fileName, foregroundColor, backgroundColor.

## `defaultType` (type: `string`):

Type used for entries that are just a text value (no type). Example: url.

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

File format for every code (an entry can override it). PNG for screens and print, SVG for scalable vector art, PDF for documents. Example: svg.

## `errorCorrection` (type: `string`):

How much damage a QR code survives. L 7%, M 15%, Q 25%, H 30%. Higher makes a denser code. A logo forces H. Example: Q.

## `boxSize` (type: `integer`):

Pixels per QR module (each little square). Bigger gives a larger image. Example: 10.

## `border` (type: `integer`):

Quiet zone around the QR code, in modules. Scanners need at least 4. Example: 4.

## `foregroundColor` (type: `string`):

Color of the dark squares or bars. Hex. Keep it dark on a light background so it scans. Example: #000000.

## `backgroundColor` (type: `string`):

Background color. Hex. Example: #ffffff.

## `logoUrl` (type: `string`):

Optional. Direct link to a PNG, JPG or WebP logo that is placed in the center of every QR code. Error correction is raised to H. Example: https://example.com/logo.png.

## `logoSizePercent` (type: `integer`):

Logo width as a percent of the QR code (5 to 30). Over 25 may stop codes from scanning. Example: 20.

## `moduleWidth` (type: `integer`):

Width of the thinnest bar of a barcode in pixels. Bigger gives a larger image. Example: 3.

## `barHeight` (type: `integer`):

Height of the bars in pixels, without the text line. Example: 100.

## `quietZone` (type: `integer`):

Empty space left and right of a barcode, in bar widths. Scanners need about 10. Example: 10.

## `showText` (type: `boolean`):

Print the digits or characters under the barcode.

## `autoCheckDigit` (type: `boolean`):

EAN-13, EAN-8, UPC-A, ISBN-13 and ITF-14 values without their check digit (12, 7, 11, 12, 13 digits) get it computed. When off, only complete values are accepted. A wrong check digit is always reported as an error.

## `code39Checksum` (type: `boolean`):

Add the optional modulo-43 check character to Code 39 barcodes. Code 128 always includes its own check automatically.

## `maxItems` (type: `integer`):

Most codes generated in this run. Entries beyond this are skipped and not charged. Example: 100.

## Actor input object example

```json
{
  "items": [
    {
      "type": "url",
      "value": "https://apify.com"
    },
    {
      "type": "code128",
      "value": "APIFY-0001"
    },
    {
      "type": "ean13",
      "value": "5901234123457"
    }
  ],
  "defaultType": "text",
  "format": "png",
  "errorCorrection": "M",
  "boxSize": 10,
  "border": 4,
  "foregroundColor": "#000000",
  "backgroundColor": "#ffffff",
  "logoSizePercent": 20,
  "moduleWidth": 3,
  "barHeight": 100,
  "quietZone": 10,
  "showText": true,
  "autoCheckDigit": true,
  "code39Checksum": false,
  "maxItems": 100
}
```

# Actor output Schema

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

One row per item with the signed download link of its image, as JSON, CSV, Excel and more.

## `records` (type: `string`):

Key-value store records: the run summary, notes on any problems, and the code files.

# 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 = {
    "items": [
        {
            "type": "url",
            "value": "https://apify.com"
        },
        {
            "type": "code128",
            "value": "APIFY-0001"
        },
        {
            "type": "ean13",
            "value": "5901234123457"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("data-done-right/qr-code-barcode-generator").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 = { "items": [
        {
            "type": "url",
            "value": "https://apify.com",
        },
        {
            "type": "code128",
            "value": "APIFY-0001",
        },
        {
            "type": "ean13",
            "value": "5901234123457",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("data-done-right/qr-code-barcode-generator").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 '{
  "items": [
    {
      "type": "url",
      "value": "https://apify.com"
    },
    {
      "type": "code128",
      "value": "APIFY-0001"
    },
    {
      "type": "ean13",
      "value": "5901234123457"
    }
  ]
}' |
apify call data-done-right/qr-code-barcode-generator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,data-done-right/qr-code-barcode-generator"
        }
    }
}
```

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/BOHYdaHvSnWhSzIgS/builds/zP2Uvy9cCTUD4mnJz/openapi.json
