Generate, decode and validate a QR code
Create a QR image, decode it back to text and check a structured payload before distributing it.
This guide describes production API usage. The website demo has a separate, smaller anonymous allowance. Subscribe to an available listing before running the scripts.
Choose your marketplace
The complete scripts below target RapidAPI. Use the provider tabs for the matching base URL and authentication pattern; ApyHub capabilities may be split across listings and remain unavailable until published. Never use a pending listing as a production endpoint.
import os
import httpx
base_url = "https://qr-barcode-api-generate-style-decode-validate.p.rapidapi.com"
headers = {
"X-RapidAPI-Key": os.environ["RAPIDAPI_KEY"],
"X-RapidAPI-Host": "qr-barcode-api-generate-style-decode-validate.p.rapidapi.com",
}
payload = {
"data": "https://example.com",
"options": {
"format": "png",
"size": 384,
},
}
response = httpx.post(
base_url + "/v1/generate",
headers=headers, json=payload, timeout=120
)
response.raise_for_status()
with open("result.png", "wb") as output:
output.write(response.content)This tutorial exercises a complete QR workflow: generate a code, decode the rendered image, then validate structured content against a published standard. All three endpoints are available on the BASIC plan.
Before you start
Subscribe to the API and export the host and key shown by RapidAPI:
export RAPIDAPI_HOST='qr-barcode-api-generate-style-decode-validate.p.rapidapi.com'
export RAPIDAPI_KEY='your-key-from-rapidapi'
1. Generate a QR code as JSON
curl --fail-with-body --max-time 45 --request POST \
--url "https://${RAPIDAPI_HOST}/v1/generate" \
--header 'content-type: application/json' \
--header "x-rapidapi-host: ${RAPIDAPI_HOST}" \
--header "x-rapidapi-key: ${RAPIDAPI_KEY}" \
--data '{"data":"https://example.com/orders/1042"}' \
--output generated.json
The file contains a base64 data_uri plus the generated QR metadata.
2. Decode the generated image
If jq is installed, build the decode request without copying the long data URI:
jq '{image_base64: .data_uri, formats: ["qr"], multiple: false}' \
generated.json | tee decode-request.json
curl --fail-with-body --max-time 45 --request POST \
--url "https://${RAPIDAPI_HOST}/v1/decode" \
--header 'content-type: application/json' \
--header "x-rapidapi-host: ${RAPIDAPI_HOST}" \
--header "x-rapidapi-key: ${RAPIDAPI_KEY}" \
--data @decode-request.json
The response lists the detected symbol, decoded text, position and orientation.
For recognized typed content it also includes parsed fields. Confirm that the
decoded text is https://example.com/orders/1042 before distributing the code.
For an existing image, send either image_base64 or a public image_url, but
not both. Decode accepts images up to 5 MB and 24 megapixels.
3. Validate a GS1 Digital Link payload
Generation and decoding prove that pixels can round-trip. Standards validation answers a different question: whether structured content follows the selected specification.
curl --fail-with-body --max-time 45 --request POST \
--url "https://${RAPIDAPI_HOST}/v1/standards/validate" \
--header 'content-type: application/json' \
--header "x-rapidapi-host: ${RAPIDAPI_HOST}" \
--header "x-rapidapi-key: ${RAPIDAPI_KEY}" \
--data '{
"standard": "gs1-digital-link",
"payload": "https://id.gs1.org/01/09520123456788/10/ABC123"
}'
Inspect valid, fields, errors and warnings. An invalid result is still a
successful API response: it means the validator processed the payload and found
specification problems.
Supported standards are gs1-digital-link, epc-sepa, swiss-qr-bill,
pix-br-code, upi and emvco-mpm. Use GET /v1/standards/fixtures for
known-good and known-bad reference payloads.
Validation is deterministic conformance checking, not certification by a payment scheme or standards body.
Complete Python example
Requires Python 3.10+ and requests (python -m pip install requests). Save as
qr_example.py and run python qr_example.py after setting RAPIDAPI_KEY.
The order URL is fictitious; protect any sensitive content and generated QR files.
import base64
import os
from pathlib import Path
import requests
HOST = "qr-barcode-api-generate-style-decode-validate.p.rapidapi.com"
HEADERS = {"x-rapidapi-host": HOST, "x-rapidapi-key": os.environ["RAPIDAPI_KEY"]}
payload = {'data': 'https://example.com/orders/1042'}
response = requests.post(f"https://{HOST}/v1/generate", headers=HEADERS, json=payload, timeout=45)
response.raise_for_status()
result = response.json()
encoded = result["data_uri"].split(",", 1)[1]
Path("qr.png").write_bytes(base64.b64decode(encoded, validate=True))
decoded = requests.post(
f"https://{HOST}/v1/decode", headers=HEADERS,
json={"image_base64": result["data_uri"], "formats": ["qr"], "multiple": False},
timeout=45,
)
decoded.raise_for_status()
print(decoded.json())
print("saved qr.png")
Errors, pacing and allowance
Check the HTTP status before using a response file. Fix 422 request errors; a 403
plan_excludes_feature needs a plan that includes the feature. Retry temporary
429/502/503/504 responses only with a bounded delay, honoring Retry-After.
Monthly quota exhaustion cannot be fixed with retries. Each call, including a
separate decode or validation step and retries, may consume allowance. Keep within
your current plan’s rate limit. A 45-second client timeout is a finite client
budget, not a service-latency guarantee. See the Developer guide and Privacy Notice.
Make it part of your application.
Get credentials and a production allowance from an available marketplace.