NewConnect Claude, Gemini, ChatGPT, and other AI agents to API Ninjas via our MCP server

How to Generate QR Codes in Python

QR Code APIUpdated August 28, 2026
Create a free API key and it will be pre-filled into every code sample on this page. No credit card required.
Generating a QR code in Python takes one GET request to the QR Code API — the response body is the image, so you write it straight to a file. No imaging libraries to install, nothing to render locally. This guide covers the basic call, sizing and colors, and the payload formats phones understand natively: URLs, Wi-Fi credentials, and contact cards.

Prerequisites

You need three things:

  • Python 3.8 or newer.
  • The requests library.
  • A free API Ninjas API key — issued instantly, no credit card. If you already have an account, it's on your profile page.
shell
pip install requests

Step 1: Generate your first QR code

The endpoint is /v1/qrcode. Pass the text to encode as data and ask for format=png. Unlike most endpoints, the response is not JSON — the body is the PNG itself, so write response.content in binary mode:

qr.py
import requests response = requests.get( 'https://api.api-ninjas.com/v1/qrcode', params={'data': 'https://api-ninjas.com', 'format': 'png'}, headers={'X-Api-Key': 'YOUR_API_KEY'}, timeout=10, ) response.raise_for_status() with open('qr.png', 'wb') as f: f.write(response.content) print(f'Wrote qr.png ({len(response.content)} bytes)')

Open qr.png and scan it with your phone — it resolves to the encoded URL. The two habits that matter: always 'wb' when writing, and never response.json() on an image response.

Step 2: Set size and colors

Three optional parameters control the output:

ParameterDefaultMeaning
size256Image width/height in pixels. Use 512+ for print.
fg_color000000Module color — 6-digit hex, no leading #.
bg_colorffffffBackground color — 6-digit hex, no leading #.

Wrapped as a function with the key in an environment variable and a shared session, the client looks like this:

qr_client.py
import os import requests API_URL = 'https://api.api-ninjas.com/v1/qrcode' session = requests.Session() session.headers['X-Api-Key'] = os.environ.get('API_NINJAS_KEY', 'YOUR_API_KEY') def generate_qr( data: str, output: str, size: int = 256, fg: str = '000000', bg: str = 'ffffff', ) -> None: """Generate a QR code PNG and write it to the output path.""" response = session.get( API_URL, params={'data': data, 'format': 'png', 'size': size, 'fg_color': fg, 'bg_color': bg}, timeout=10, ) response.raise_for_status() with open(output, 'wb') as f: f.write(response.content) generate_qr('https://api-ninjas.com', 'site.png', size=512) print('Wrote site.png')

Brand colors work as long as you keep contrast high — scanners need it:

brand.py
# Brand-colored: blue modules on a light-gray background generate_qr( 'https://api-ninjas.com', 'brand.png', size=512, fg='1664ea', bg='f6f9fc', )

Step 3: Encode real payloads

A QR code encodes arbitrary text, and phones treat certain formats specially. A vCard block becomes an “add contact” prompt:

vcard.py
vcard = '''BEGIN:VCARD VERSION:3.0 FN:Jane Doe ORG:Acme Inc. TEL:+1-555-0100 EMAIL:jane@example.com END:VCARD''' generate_qr(vcard, 'jane-vcard.png', size=512)

And a WIFI: string joins the network on scan — the classic guest-Wi-Fi poster:

wifi.py
# Scanning this joins the guest Wi-Fi automatically wifi = 'WIFI:T:WPA;S:GuestNetwork;P:correcthorsebatterystaple;;' generate_qr(wifi, 'guest-wifi.png')

Step 4: Generate in bulk

Table tents, event badges, per-page posters — bulk generation is a loop over payloads, one file per code:

batch.py
urls = { 'home': 'https://api-ninjas.com', 'pricing': 'https://api-ninjas.com/pricing', 'docs': 'https://api-ninjas.com/api', } for name, url in urls.items(): generate_qr(url, f'{name}.png') print(f'Wrote {name}.png')

Step 5: Handle errors

The failure modes are simple: empty data (400), a missing key (401), and rate limits on big batches (429):

errors.py
from requests.exceptions import HTTPError, RequestException try: generate_qr('', 'empty.png') # empty data is rejected except HTTPError as error: status = error.response.status_code if status == 400: print('Bad request — data must not be empty') elif status == 401: print('Missing or invalid API key') elif status == 429: print('Rate limit exceeded — slow the batch down') else: print(f'HTTP {status}: {error.response.text}') except RequestException as error: print(f'Network error: {error}')

Where to go from here

For retail-style linear barcodes, the Barcode API follows the same request-and-save pattern. The complete script — payload and output file as command-line arguments — is below.

qr_codes.py

The complete script from this guide: colors, sizing, and command-line payload and output arguments.

Frequently asked questions

What does the endpoint return?

Raw image bytes, not JSON. Write response.content to a file opened in binary mode ("wb") — calling response.json() on an image response fails.

Can I customize the QR code colors?

Yes — pass fg_color and bg_color as 6-digit hex codes without the leading #, for example fg_color=1664ea. Keep strong contrast between the two or scanners will struggle.

What size should I generate?

The size parameter sets the image dimensions in pixels (default 256). Use 512 or larger for print — small codes with long payloads become too dense to scan reliably.

Can I encode Wi-Fi credentials or contact cards?

Yes. QR codes encode arbitrary text, and phones recognize standard payload formats: WIFI:T:WPA;S:name;P:password;; joins a network, and a BEGIN:VCARD block adds a contact.

Is there a limit on how much data a QR code can hold?

The QR standard tops out around 3KB, but practical scanning degrades long before that. Keep payloads short — for long URLs, encode a short link instead.