Add a logo to a QR code
Drop a logo into the middle of a QR code carelessly and you can break it — the center is exactly where error correction has the least room to compensate. This API places your logo inside a QR code using the layout and error-correction headroom needed to keep it reliably scannable, so the branded version works as well as the plain one.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Why a logo in the middle is riskier than it looks
A QR code's error correction can reconstruct a certain percentage of missing or obscured data, and that budget is what makes overlaying a logo possible at all — but it isn't unlimited. Push the logo too large, position it off-center, or drop the correction level too low for the amount of coverage, and you get a QR code that looks fine to a human eye and fails intermittently on real phone cameras, often in exactly the lighting or angle conditions you didn't test. dev.qr_logo is built to keep that trade-off inside safe bounds automatically.
What happens when you call it
You submit the QR payload — a URL, WiFi credentials, a vCard or plain text, same options as standard generation — along with your logo image, and the output format. The task runs asynchronously with a task_id returned immediately, and the branded code arrives by signed webhook or a 24-hour signed link once it's rendered, sized and validated. Choose PNG for a fixed-size use like a printed flyer, or SVG when the branded code needs to scale across different packaging or display sizes.
What 'verified scannable' actually means here
Adding a logo isn't just an image composite — it means selecting an error-correction level high enough to absorb the logo's footprint, sizing the logo so it doesn't exceed the safe coverage area, and preserving enough quiet zone around the whole code. The generation process accounts for all three automatically based on your logo, rather than leaving you to guess at the right correction level and find out only when someone can't scan the finished code.
Where branded QR codes actually get used
Retail packaging and shelf talkers where the QR needs to look like part of the brand, not a bolted-on afterthought. Event signage and lanyards where a plain black-and-white square would look generic next to the rest of the event's design system. Print ads and menus where a scannable code doubles as a small piece of brand real estate. Anywhere a company wants the code itself to be recognizable at a glance, before anyone even scans it.
Fitting branded codes into a design or catalog pipeline
Because this runs through the same async pattern as everything else, you can generate a full set of branded, per-SKU or per-location QR codes from a script — a product catalog import, a batch of event badges, a set of location-specific menus — and let each one land as its own webhook once it's rendered and validated, rather than exporting and checking codes one at a time in a design tool.
What you can do with it
Branded product packaging
Add your logo to the QR code linking to product information, so the code reads as part of the package design instead of a generic sticker.
Event badges and signage
Generate logo-embedded QR codes for lanyards and posters that match the rest of an event's branded materials.
Print menus and ads
Place a branded QR code linking to an online menu or landing page directly in a print ad without it looking out of place next to the logo.
Partner and franchise materials
Produce branded QR codes at scale for multiple franchise locations, each with its own destination link but the same recognizable logo mark.
FAQ
Will a logo make my QR code stop working?
Not if it's placed and sized correctly, which is exactly what this endpoint handles — it adjusts error correction and logo coverage automatically to keep the code reliably scannable.
What image formats does the logo need to be in?
Standard raster image formats work as the logo input; the output QR code itself is delivered as PNG or SVG, your choice.
Can I use any QR payload type with a logo?
Yes — URL, WiFi credentials, vCard and plain text all support a logo overlay, the same payload options as standard QR generation.
Is this free to test?
The tool above runs free in your browser. The API is paid — each call draws from your prepaid ForHosting KIT balance: top up from $10.00 (it never expires), pay each request's published price, and a call with no balance returns HTTP 402. No subscription, no tokens, and a failed task is never charged.
What does it cost?
0.002 dollars per request plus 0.005 dollars per generated image.
How is this different from the standard QR generator?
The standard generator produces a plain QR code; this endpoint embeds and validates a logo inside it while preserving reliable scannability, which the standard endpoint doesn't attempt.
Can I generate branded QR codes in bulk?
Yes — submit each generation asynchronously and collect the results as webhooks arrive, which suits batch jobs like per-location or per-SKU logo QR codes.
Are failed generations billed?
No — failed tasks are retried up to three times and only successful results are charged.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/qr-logo \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"image":"https://ejemplo.com/imagen.jpg"}'const res = await fetch("https://api.kit.forhosting.com/dev/qr-logo", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"image": "https://ejemplo.com/imagen.jpg"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/qr-logo",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"image": "https://ejemplo.com/imagen.jpg"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/qr-logo", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"image":"https://ejemplo.com/imagen.jpg"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"image":"https://ejemplo.com/imagen.jpg"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/qr-logo", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"image": "https://ejemplo.com/imagen.jpg"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.qr_logo",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |