Your agent can write a blog post, pull from a CRM, send a Slack message, schedule an email. What it can't do is hand someone something to scan.
That's the wall most agent builders hit a few integrations in: the agent produces text, structured data, and links — but the moment a workflow needs a printed artifact (a table tent, a return label, an event badge, a WiFi card), raw URLs fall apart. They get mistyped, shortened, abandoned.
A QR code API closes that gap. It turns whatever your agent generates into something a phone camera captures in ~1 second. Below is the working pattern for Claude (tool use) and ChatGPT (function calling), using a dynamic QR API with a free tier (1,250 calls/month, no credit card required).
The API in 60 seconds
The surface area fits on one screen.
-
Auth: Bearer token in the
Authorizationheader. -
Base URL:
https://qrchameleon.com/api/v1/ -
Core call:
POST /urls/bulk— creates one or more dynamic short links (up to 100/request), each of which auto-generates a downloadable QR code.
curl -X POST https://qrchameleon.com/api/v1/urls/bulk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls": [
{
"destination_url": "https://example.com/launch",
"title": "Spring product launch",
"utm_source": "agent",
"utm_medium": "qr",
"utm_campaign": "spring-2026"
}
]
}'
Response:
{
"success": true,
"data": {
"items": [
{
"index": 0,
"status": "created",
"short_url": "https://qrch.am/U4im626B",
"short_code": "U4im626B",
"destination_url": "https://example.com/launch"
}
]
}
}
The short_url is a tracked, dynamic redirect — you can repoint it later without regenerating the printed code, and every scan is logged. For agent workflows, dynamic is the only option that makes sense (here's the static vs. dynamic breakdown if you want the why).
That's 90% of what you need. Now wire it into your model.
Claude (Anthropic tool use)
You define create_qr_code as a tool, Claude decides when to call it, and your code executes the actual request.
import os
import requests
import anthropic
client = anthropic.Anthropic()
QR_API_KEY = os.environ["QR_CHAMELEON_API_KEY"]
# 1. Define the tool Claude can call
qr_tool = {
"name": "create_qr_code",
"description": (
"Generate a dynamic, trackable QR code for any URL. Returns a short "
"URL (qrch.am/...) whose QR is generated automatically. Use whenever "
"the user needs a QR for printed material, packaging, signage, or any "
"handoff between digital and physical."
),
"input_schema": {
"type": "object",
"properties": {
"destination_url": {"type": "string", "description": "URL the QR should redirect to."},
"title": {"type": "string", "description": "Label for finding this QR later."},
"utm_campaign": {"type": "string", "description": "Optional campaign tag for analytics."},
},
"required": ["destination_url"],
},
}
# 2. The function that actually calls the QR API
def create_qr_code(destination_url, title="", utm_campaign=""):
payload = {"urls": [{
"destination_url": destination_url,
"title": title,
"utm_source": "claude-agent",
"utm_medium": "qr",
"utm_campaign": utm_campaign or "default",
}]}
r = requests.post(
"https://qrchameleon.com/api/v1/urls/bulk",
headers={"Authorization": f"Bearer {QR_API_KEY}"},
json=payload,
timeout=10,
)
r.raise_for_status()
item = r.json()["data"]["items"][0]
return {"short_url": item["short_url"], "short_code": item["short_code"]}
# 3. The agent loop — Claude requests the tool, you execute, feed the result back
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
tools=[qr_tool],
messages=[{
"role": "user",
"content": (
"We just shipped a pricing page at https://example.com/pricing. "
"Generate a QR code for the trade-show booth banner."
),
}],
)
for block in response.content:
if block.type == "tool_use" and block.name == "create_qr_code":
result = create_qr_code(**block.input)
print(f"Booth banner QR: {result['short_url']}")
In a real loop you'd return result to Claude as a tool_result block and let it respond naturally — see Anthropic's tool use docs. The division of labor is the point: Claude decides a QR is needed; your code produces it.
ChatGPT (OpenAI function calling)
Same shape, OpenAI's schema. (For Custom GPTs in the ChatGPT app, the same endpoint wires in as a GPT Action.)
import os
import requests
from openai import OpenAI
client = OpenAI()
QR_API_KEY = os.environ["QR_CHAMELEON_API_KEY"]
tools = [{
"type": "function",
"function": {
"name": "create_qr_code",
"description": "Generate a dynamic QR code that redirects to any URL. Returns a tracked short URL.",
"parameters": {
"type": "object",
"properties": {
"destination_url": {"type": "string"},
"title": {"type": "string"},
"utm_campaign": {"type": "string"},
},
"required": ["destination_url"],
},
},
}]
def create_qr_code(destination_url, title="", utm_campaign=""):
r = requests.post(
"https://qrchameleon.com/api/v1/urls/bulk",
headers={"Authorization": f"Bearer {QR_API_KEY}"},
json={"urls": [{
"destination_url": destination_url,
"title": title,
"utm_source": "chatgpt-agent",
"utm_medium": "qr",
"utm_campaign": utm_campaign or "default",
}]},
timeout=10,
)
r.raise_for_status()
return r.json()["data"]["items"][0]
From here it's the standard function-calling loop: pass tools to client.chat.completions.create(...), check the response for a tool call, run create_qr_code(**args), and return the result as a tool message.
Where this shows up
It's not that agents need QR codes — workflows do. A few patterns that keep recurring:
- Support agents generating a unique, tracked return/refund QR code per customer.
- Marketing agents attaching a UTM-tagged QR code to every asset they ship, so attribution lands with no wasted man hours in the middle.
- Event agents generating one QR code per RSVP that doubles as the day-of check-in QR code.
- Inventory/asset agents provisioning a dynamic, repointable QR code per asset at creation time.
The unifying thread: the agent isn't just writing text — it's producing something the physical world consumes, and the QR code is the handoff.
The rest (Gemini, Grok, MCP)
Gemini and Grok follow the identical "define a tool / execute the call" pattern, and there's a reusable MCP server approach so any MCP-compatible agent can create QR codes without custom wiring. Full working code for all four models plus the MCP server is in the complete guide:
👉 QR Code API for AI Agents: Claude, ChatGPT, Gemini & Grok
The REST API is on every plan, free tier included (1,250 requests/month, no credit card required) — enough to prototype an agent tool without ever paying.
Top comments (0)