# Using IronQR with AI Coding Assistants
IronQR is Iron Software's QR code library for .NET. It writes standard QR, Micro QR, and rMQR symbols, styles them with logos and colors, and reads them back with a machine learning detector. Its guides and samples are public, so coding assistants may have met the API in training.
Training does not pin the release in your project. Assistants referencing current documentation generate code that follows its runtime rules, while those relying on memory may produce code that compiles but fails at runtime.
This guide covers two types of tools.
- **Assistants** work in the editor, completing lines or rewriting methods, like GitHub Copilot's inline suggestions.
- **Agents** take whole tasks, editing files, running builds and programs, and returning results for review, as Claude Code, Cursor, ChatGPT Codex, and Google Antigravity do.
Both need the same setup. Install the package, load the license key from the environment, provide IronQR's machine-readable documentation, and decode each saved QR image with IronQR's reader, whether you are [generating a code with a logo](https://ironsoftware.com/qr/csharp/how-to/add-custom-logo-qr-code/), [selecting an error correction level](https://ironsoftware.com/qr/csharp/how-to/error-correction-qr-code/), [reading the QR type](https://ironsoftware.com/qr/csharp/how-to/read-qr-code-type/), or [choosing a scan mode](https://ironsoftware.com/qr/csharp/how-to/read-qr-codes-with-scan-modes/).
<div class="flex flex-wrap items-center gap-x-14 gap-y-6 py-4">
<img src="/static-assets/svgs/ai-coding-agents/claude.svg" alt="Claude Code logo" width="48" height="48" />
<img src="/static-assets/svgs/ai-coding-agents/codex.svg" alt="ChatGPT Codex logo" width="48" height="48" />
<img src="/static-assets/svgs/ai-coding-agents/github-copilot-black.svg" alt="GitHub Copilot logo" width="48" height="48" />
<img src="/static-assets/svgs/ai-coding-agents/cursor-black.svg" alt="Cursor editor logo" width="48" height="48" />
<img src="/static-assets/svgs/ai-coding-agents/antigravity.svg" alt="Google Antigravity logo" width="48" height="48" />
</div>
<div class="hsg-featured-snippet">
<h2>How to Use IronQR with an AI Coding Assistant</h2>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://www.nuget.org/packages/IronQR/">Download the C# QR code library from NuGet</a></li>
<li>Load the license key from an environment variable before the first write or read</li>
<li>Give the assistant IronQR's <code>llms.txt</code> so it starts from the real API</li>
<li>Save the IronQR rules in the file your assistant reads at the start of a session</li>
<li>Send the one-shot setup prompt in a fresh session</li>
<li>Build, then decode every saved QR image and compare it with the value written</li>
</ol>
</div>
<br class="clear" />
## Can't My AI Assistant Handle QR Codes on Its Own?
IronQR publishes documentation built for tools to read, which shows the options each symbol type accepts and what the reader returns in each scan mode.
The library matters too. Almost any QR package prints a black square that scans on a screen. The gaps appear with branded codes, photographed tickets, and small symbols.
- **A changed background color is not checked:** a code on a dark background saves without an error and then fails to decode.
- **Phone photos are harder than generated images:** a section below measures which scan mode reads each kind of damage.
- **Rebuilding detection costs tokens:** an assistant that writes its own thresholding to rescue scans spends a paid attempt on every try, and repeats the work for each new kind of failing photo.
- **Small symbols are built in:** Micro QR and rMQR come from the same write call as standard QR, so seat numbers and narrow labels do not need a second library.
- **The package and the namespace differ:** the NuGet package is `IronQR` and the namespace is `IronQr`. A guessed package name can also resolve to a lookalike that attackers publish on purpose, a practice called *slopsquatting*. Spell out both names in the prompt.
- **The license terms are known in advance:** IronQR licenses are perpetual, and the [licensing page](https://ironsoftware.com/qr/csharp/licensing/) shows how many developers, locations, and projects each tier covers.
<hr class="separator" />
## Step 1: Install IronQR
With the package referenced, the assistant sees IronQR's real types as it writes code.
```text
Add IronQR from NuGet to this project, run a restore, and report the
version number that NuGet resolved.
```
To pin a release from the terminal instead, name it.
```shell
dotnet add package IronQR --version 2026.10.1
```
Plain `IronQR` brings the Windows native reader and the detection model, a 44 MB `IronQrDetection.dll` that pulls in `Microsoft.ML.OnnxRuntime` 1.20.1, so container images and serverless bundles should budget for it. Linux and Docker use `IronQR.Linux`, Macs use `IronQR.MacOs` or `IronQR.MacOs.ARM`, and mobile apps use `IronQR.iOS` or `IronQR.Android`. All six were published at 2026.10.1, and the [NuGet packages guide](https://ironsoftware.com/qr/csharp/get-started/nuget-packages/) explains the choice. `IronQR.Slim` leaves the model out. It still reads in Auto and OnlyBasicScan but throws IronQrException in OnlyDetectionModel. On Windows it also needs `IronSoftware.ReaderInternals.Windows`.
---
## Step 2: Apply Your License Key
IronQR does not produce watermarked trial output. Without a license key, every write and read call fails with IronSoftware.Exceptions.LicensingException and the text "Production License Required". A mistyped key fails at the same calls with "License Key Not Recognized". A free trial key is available below.
!!!--LIBRARY_START_TRIAL_BLOCK--!!!
Set the key once at startup through `IronQr.License.LicenseKey`, before any IronQR call, and read it from an environment variable to keep it out of the repository.
```csharp
IronQr.License.LicenseKey = Environment.GetEnvironmentVariable("IRONQR_LICENSE_KEY");
```
`IronQr.License.IsLicensed` reports true after a valid key is set, and the same class has a method that tests a key without applying it. The exception type is not public, so a catch clause that names it fails to compile with CS0122. Catch `Exception` and inspect the message instead.
[[i:([IronQR License Keys](https://ironsoftware.com/qr/csharp/get-started/license-keys/) covers `Web.config`, `appsettings.json`, and the other places a key can be kept.)]]
---
## Step 3: Point Your Assistant at IronQR's LLM Documentation
- [`llms.txt`](https://ironsoftware.com/qr/csharp/llms.txt) lists one line per page and is the first read of every session.
- Summaries of all 44 pages come in one fetch from [`llms-full.txt`](https://ironsoftware.com/qr/csharp/llms-full.txt).
- [`llms-full-catalog.txt`](https://ironsoftware.com/qr/csharp/llms-full-catalog.txt) adds the blog posts to the index.
- The [API Reference](https://ironsoftware.com/qr/csharp/object-reference/api/) settles whether a member exists.
- Packages, licensing, recipes, and fixes are in [`skill.md`](https://ironsoftware.com/qr/csharp/skill.md).
When a task depends on one guide's detail, have the assistant open that page.
Combine the index with a direct instruction.
```text
Open https://ironsoftware.com/qr/csharp/llms.txt before you write IronQR code
and keep to the members it documents. Creating a code goes through
QrWriter.Write with an optional QrOptions, and reading goes through
new QrReader().Read on a QrImageInput, so do not look for one class that does
both. When a member is not in the index, check
https://ironsoftware.com/qr/csharp/object-reference/api/, and tell me it is
missing rather than inventing it.
```
---
## Step 4: Add IronQR Context to Your Project
A chat forgets its instructions when it ends, and a project file is read at the start of every session. Put the IronQR rules in the file your team uses. Claude Code reads `CLAUDE.md`, ChatGPT Codex reads `AGENTS.md`, and GitHub Copilot reads `.github/copilot-instructions.md`. Cursor reads `.cursor/rules/*.mdc` or `AGENTS.md`, and Google Antigravity reads AGENTS.md or `GEMINI.md`. The wording can be the same in each, although a Cursor rule file also needs MDC frontmatter.
```markdown
## QR codes with IronQR
All QR work in this project uses IronQR. NuGet package `IronQR` (`IronQR.Linux` on Linux and Docker), namespace `IronQr`, enums in `IronQr.Enum`.
- Docs index: https://ironsoftware.com/qr/csharp/llms.txt
- Skill file: https://ironsoftware.com/qr/csharp/skill.md
- Write with `QrWriter.Write(value, new QrOptions(...))`, style with `QrStyleOptions`, read with `new QrReader().Read(new QrImageInput(bitmap))`.
- Set `IronQr.License.LicenseKey` from IRONQR_LICENSE_KEY at startup. Never put the key in a file.
- Pass an explicit `QrErrorCorrectionLevel` that the symbol type accepts. Micro QR rejects `Highest`, rMQR rejects `Low` and `High`.
- Release a `QrImageInput` with `input.Dispose()`, not a `using` statement.
- Decode every saved image with `QrReader` and compare it with the written value before calling a change done.
- Do not add a second QR library. If IronQR cannot do something, say so.
```
Four things in the current skill file need correcting. Its single-file example pins 2026.8.1 while NuGet serves 2026.10.1. Its frame-reading recipe wraps the image input in a `using` declaration, and its first recipe and its styling advice pass a file path to `Verify`, two of the mistakes Step 7 describes. And it lists `Highest` as invalid for rMQR, which the error correction table below contradicts.
---
## Step 5: One-Shot Setup Prompt
Steps 1 through 4 fit in one message at the start of a session.
```text
Set this project up for QR code work with IronQR, then save the rules below
where your future sessions will read them.
- Add the IronQR NuGet package (IronQR.Linux for a Linux or Docker host).
The namespace is IronQr, spelled with a lowercase r.
- Assign IronQr.License.LicenseKey from the IRONQR_LICENSE_KEY environment
variable before the first QrWriter or QrReader call. Keep the key out of
every file you create or commit.
- Fetch https://ironsoftware.com/qr/csharp/llms.txt first and write against
the members it documents. Look up anything else in the API reference at
https://ironsoftware.com/qr/csharp/object-reference/api/ before using it.
- If your tool loads skill files, add
https://ironsoftware.com/qr/csharp/skill.md, but trust a compiler error
over the skill when the two disagree.
- After any change that writes a QR image, decode the saved file with
QrReader and compare the value with the one you wrote.
```
[[t:(Open the Step 4 project file afterward to confirm the rules landed.)]]
---
## Step 6: Prompt Patterns That Produce Working Code
Name the symbol type, the error correction level, and the style.
> **Vague** *Generate a QR code for the ticket with our logo.*
>
> **Better** *Write the ticket ID with `QrWriter.Write` at the `Highest` error correction level, save it at 300 pixels with the logo at 28 percent of that width, and catch `IronQrException` if IronQR refuses the style.*
Give the release and the framework, because defaults and validation rules change between versions.
> **Better** *Target .NET 9 and IronQR 2026.10.1.*
Ask for complete files. A fragment drops the `IronQr.Enum` directive that the encoding and scan mode enums need, and it hides where the key is assigned.
> **Better** *Return all of `Program.cs` with its using directives and the license line, ready to build as it is.*
---
## Step 7: Verify What You Get Back
- **Disposing the image input with `using`:** `QrImageInput` implements IDisposable with a method that throws NotImplementedException, so a using block or declaration fails after the read succeeds. Call its public `Dispose` method directly instead.
- **Reading with the detection model alone:** `OnlyDetectionModel` returns where codes are, with an empty value and a QR type of None. The [scan modes guide](https://ironsoftware.com/qr/csharp/how-to/read-qr-codes-with-scan-modes/) explains when to use `Auto` or `OnlyBasicScan` for values.
- **Treating `Verify` as a file check:** it compares the code in memory with the string you pass, so a file path returns false. Decode the saved PNG with `QrReader` to prove the file scans.
- **Empty write options:** `QrOptions` built with no arguments has its encoding set to None, and `QrWriter.Write` rejects it with *None is not a valid encoding*. Pass the level, and the encoding when it is not standard QR.
### Let the Agent Verify Its Own Work
Hand the checks back to the assistant and ask for the evidence.
```text
Rebuild in Release and run it. List each IronQR type and member the code uses
next to the documentation page that shows it, print IronQr.License.IsLicensed,
then reopen every PNG the program saved with QrReader and give me a table of
file, value written, value decoded, QrType, and whether they agree.
```
---
## Which Error Correction Level Does Each Symbol Type Accept?
The four `QrErrorCorrectionLevel` members do not follow the letters of the QR standard. `High` is level Q, and `Highest` is level H, which IronQR's XML documentation describes as leaving room for a logo. Micro QR and rMQR accept only some of them, and the write call throws IronQrEncodingException for the rest, with a message such as *Highest is not valid for Micro QR*.
| Member | QR standard | Micro QR | rMQR |
|---|---|---|---|
| `Low` | L, about 7% recoverable | accepted | throws |
| `Medium` | M, about 15% | accepted | accepted |
| `High` | Q, about 25% | accepted | throws |
| `Highest` | H, about 30% | throws | accepted |
`QrWriter.Write` with no options writes standard QR at Highest, and the options constructors also default to Highest, which is why Micro QR options fail until you pass a lower level. The [supported formats page](https://ironsoftware.com/qr/csharp/get-started/supported-qr-formats/) compares the three symbol types.
The level also caps the logo. On a 400 pixel ticket ID code in our tests, Low refused a logo at 20% of the width, Medium and High took 28% and refused 30%, and Highest took 30%. A refused logo makes `Save` throw IronQrException with *The logo size which you manually specified for your QR code is too large*. A `QrLogo` width and height of 0 lets IronQR size the logo itself, and on that code it picked 60 pixels at Low and 112 at Highest.
Foreground color is checked the same way. With a navy foreground at Highest, the same ticket ID code saved at 300 and 500 pixels but threw IronQrException at 400 with *Color: #FF1A237E makes the QR unreadable for our reading engine*. Styling code should catch that exception, change the size or color, and retry, since a style that saved at one size can fail at another.
---
## Which Default Values Does IronQR Use?
These starting values were measured in IronQR 2026.10.1 under .NET 9.
- Empty style options leave `Dimensions` and the margins at 0, so a ticket ID saves at one pixel per module, 25 x 25 pixels.
- An initializer that sets `Dimensions` still leaves the margins at 0, since it skips the constructor that sets 10.
- The `QrStyleOptions` constructor that takes a size sets margins of 10, so a size of 400 saves a 420 pixel PNG.
- `Save` with no style writes a ticket ID at 250 x 250 pixels.
- `Color` and `BackgroundColor` start as black on white.
- A new image input scans in Auto, the detection model and then a basic scan.
- `CharacterEncoding` is ISO-8859-1, so set it for characters outside Latin-1.
The [logo guide](https://ironsoftware.com/qr/csharp/how-to/add-custom-logo-qr-code/) sets a `Dimensions` of 500 in an initializer, so its output has no quiet zone around the symbol. Set `Margins` when the code will be printed next to other artwork.
---
## How Does IronQR Read Photographed Codes?
We calibrated the acceptance test below on eight seeded sets. IronQR 2026.10.1 wrote the styled logo codes at 300 pixels and the other ticket codes at 400, Pillow distorted them, and IronQR read them back. The Auto counts vary with how the values are assigned to the images, so they are ranges over 10 draws.
| Image | Sets read in Auto | Sets read in OnlyBasicScan | Fix |
|---|---|---|---|
| Scaled to 60%, rotated 30 degrees, blurred 1.5 pixels, on gray | 8 of 8 | 8 of 8 | None needed |
| Grain, standard deviation 20 gray levels | 0 of 8 | 0 of 8 | Blur first |
| Two upright codes 30 pixels apart | 5 to 7 of 8 | 8 of 8 | Add OnlyBasicScan |
| Navy logo code after a 1.5 pixel blur | 0 to 4 of 8 | 8 of 8 | Add OnlyBasicScan |
The blur that rescues the grainy code is the one that costs Auto the navy logo code. Two setups read all 12 codes on all eight sets. One applies a 1.5 pixel blur and then OnlyBasicScan. The other applies a blur of 1 to 2 pixels, runs Auto and OnlyBasicScan, and merges the results by value. Pick the setup from the images that fail, then run it unchanged for every upload.
Grain also interacts with code size. With the same grain, codes of 350 to 425 pixels failed in both modes on all 24 files, codes of 300, 500, and 600 pixels read in both, and codes of 450 and 475 pixels read only in Auto. Adding 100 pixels of white around a failing code let OnlyBasicScan read all 12 files we tried.
---
## A Result You Can Reproduce
The acceptance test is one realistic task in one prompt with no hand-written code. Paste it into a new session in an empty directory and judge the result against the pass list.
[[i:(Running it takes the .NET 9 SDK on a Windows machine with internet access, an assistant allowed to use the terminal, and an IronQR trial or production key in `IRONQR_LICENSE_KEY`.)]]
### The prompt
```text
Build a .NET 9 minimal API for event check-in that issues ticket QR codes and
reads them back from uploaded photos. Begin in an empty directory, and if you
find existing code or a project file there, report that and do nothing else.
Nobody will answer questions, so carry the job through writing, building,
running, and fixing by yourself, and settle anything left open with a
reasonable choice that you note. Keep all deliverables inside the project
directory, in the folders this prompt names.
1. Install the IronQR NuGet package pinned to version 2026.10.1.
2. Work from https://ironsoftware.com/qr/csharp/llms.txt and the guides it
points to, and call no IronQR member those pages do not document. Every
code must come from QrWriter.Write; any .NET imaging library may compose
and distort the test images afterward.
3. Take the key from IRONQR_LICENSE_KEY when the app starts and keep it out of
source and out of every file the run writes. If IronQr.License.IsLicensed
comes back false, stop with a report saying so.
4. GET /ticket/{ticketId} returns a PNG of a QR code written at
QrErrorCorrectionLevel.Highest and saved through QrStyleOptions at a
Dimensions of 400 with 10-pixel margins, with a logo in the center: a
solid square of one bright accent color, drawn by your code, whose QrLogo
width and height are each 28 to 30 percent of Dimensions. POST /checkin
accepts one uploaded image and returns JSON listing every QR code found in
it, each with its value and QR type.
5. Seed the random generator with 2026 and write 10 PNG files to testset/,
no two holding the same value: standard-01 to standard-03, each carrying a
ticket ID made of TKT- and eight random digits; pair-01, one image holding
two more ticket codes side by side and upright, with 30 pixels of
background between their dark modules; styled-01 to styled-03, ticket
codes at Highest with the step 4 logo and three different dark, saturated
foreground colors on white; micro-01 and micro-02, Micro QR codes carrying
seat numbers such as C07; and rmqr-01, an rMQR code carrying an event URL.
Save every testset code the same way at a Dimensions of 400, except 300
for the styled and Micro QR codes and 600 for rmqr-01, and resize no code
afterward unless standard-02 calls for it.
Keep standard-01 clean. Make standard-02 look photographed: scale it to 60
percent, rotate it 30 degrees, blur it with a Gaussian radius of 1.5
pixels, and center it on a 600 x 600 light gray canvas. Give standard-03
sensor grain: Gaussian noise with a standard deviation of 20 gray levels,
one value per pixel added to all three channels, over the whole image.
Record in manifest.csv each file, every value it holds, its QR type, the
error correction level used, and its distortion (none, photographed,
grain, pair, or styled).
6. Measure each saved image before /checkin is ever called, and repair the
generator whenever a measurement falls outside its range: the pixel size
step 5 implies;
on the styled codes and the /ticket output, the logo's share of the symbol
area, 7 to 10 percent; on the styled codes, the foreground's WCAG contrast
ratio against the background, 7 to 15; on the Micro QR codes, a square
symbol 11 to 17 modules wide; on the rMQR code, a symbol at least twice as
wide as it is tall; on standard-03, the mean absolute difference from the
clean code, 7 to 9 gray levels; on pair-01, the gap between the two codes'
dark modules, 28 to 32 pixels. Once /checkin has been called the first
time, the testset files are frozen: do not rewrite or edit them.
7. /checkin runs one fixed configuration for every upload: the same scan mode
or modes and the same image preparation, in the same order. It must never
open the manifest, hold a ticket ID, seat number, or URL as a literal, or
pick between results by comparing them with expected values. You choose
and change the configuration between runs; the program never does.
8. Build in Release and start the API. Request /ticket for a ticket ID drawn
from the seed that is not in the testset and save the PNG it returns as
ticket.png. POST ticket.png and every testset image to /checkin over HTTP
and save each raw response as checkin/<file name without .png>.json.
9. Write roundtrip.md with every step 6 measurement as a number for each
image (a bare pass or fail is not enough), the /checkin configuration,
and a results table with the columns file, distortion, expected value,
value read (the decoded string as the saved response holds it, even when
it is wrong), expected QR type, QR type read, and match, holding one row
per expected code, 12 rows in all. A row counts as a match only if the
decoded value equals the expected value exactly, the QR type agrees, and
the value appears in that file's saved response. An extra or repeated
code in a response fails every row of that file.
10. Until all 12 rows match, study the saved responses of the failing files,
adjust the /checkin configuration, rebuild, and repeat. Stop after the
eighth run that still has failures, and report the failing rows, each
configuration you tried, and your reading of the cause.
11. End with a brief summary covering the Release build outcome, how many
rows matched, the /checkin configuration, the measured step 6 values,
and every assumption you made.
```
### Output
<img src="/static-assets/qr/ai-agents/ai/standard-03.png" alt="Grainy test QR code that IronQR read correctly through the check-in API in the acceptance run" width="420" height="420" loading="lazy" />
This is `standard-03.png`, the grain image, 8.0 gray levels from the clean code on average. The first check-in setup, plain Auto, read the other 11 codes and missed this one. A Gaussian blur with a sigma of 1 read it but lost `styled-03.png` and `ticket.png`, and a median filter, alone or with a wider quiet zone, still missed it. The fifth setup read all 12 codes by applying a 3 by 3 median filter and a threshold at half brightness to every upload, then reading in Auto.
The unedited [round-trip table](/static-assets/qr/ai-agents/ai/roundtrip.md) lists every measurement, each setup tried, and the 12 rows. The [ticket from the API](/static-assets/qr/ai-agents/ai/ticket.png) carries an orange logo over 7.84% of the symbol.
- An independent check remeasured every requirement on the saved files, and a fresh start of the Release build returned the same 11 responses.
- Before the fifth run, Claude Code tried eight setups outside the API, and three read every code.
- Claude Code applied the prompt's Gaussian radius of 1.5 as a sigma of 1.5.
- The Steps 1, 3, 5, and 7 prompts followed in the same session, and 12 of 12 codes decoded at Step 7.
- NuGet now flags the `SixLabors.ImageSharp` 3.1.12 pin Claude Code added.
- With the code sizes left open, an earlier draft of the prompt let plain Auto read every file.
### What passes
- The Release build succeeds with no edits from you.
- Opening the images shows three different dark foregrounds under a bright square logo, grain across the whole of `standard-03.png`, and two upright codes side by side in `pair-01.png`.
[[i:(Change the version in step 1 to test another release. The [IronQR changelog](https://ironsoftware.com/qr/csharp/product-updates/changelog/) records what each one changed.)]]
### The run record
- The machine runs Windows 11 x64 on a Core i9-14900KF with 64 GB of memory.
- Every project targets .NET 9.
- Every guide ran `IronQR` 2026.10.1. Copilot and Antigravity also referenced `IronQR.Linux` 2026.10.1 for Linux builds, the Copilot starter project already carried `PDFtoImage` 5.4.0, and Cursor's last prompt moved the service to `IronQR.Slim` 2026.10.1 with `IronSoftware.ReaderInternals.Windows` 2026.3.47413.
- Each duration adds up the logged time of the prompts on that guide's page. This guide's row is the acceptance prompt alone.
- **Last tested** October 7, 2026, for all six runs.
| Guide | Assistant and version | Model | Duration (minutes) |
|---|---|---|---|
| This guide | Claude Code 2.1.277, one message, permission prompts off | Claude Opus 5 | 29.0 |
| [Claude Code](https://ironsoftware.com/qr/csharp/ai-agents/claude-code/) | Claude Code 2.1.277 on `opusplan` | Claude Opus 5 for the plan, Claude Sonnet 5 for the rest | 30.2 |
| [ChatGPT Codex](https://ironsoftware.com/qr/csharp/ai-agents/chatgpt-codex/) | Codex CLI 0.160.0 | GPT-6 Luna | 37.2 |
| [GitHub Copilot](https://ironsoftware.com/qr/csharp/ai-agents/github-copilot/) | GitHub Copilot CLI 1.0.91 | GPT-6 Luna, routed by Auto | 26.9 |
| [Cursor](https://ironsoftware.com/qr/csharp/ai-agents/cursor/) | Cursor 3.23.23 desktop app | Grok 4.7 | 50.8 |
| [Google Antigravity](https://ironsoftware.com/qr/csharp/ai-agents/antigravity/) | Antigravity CLI 1.3.1 | Gemini 3.8 Flash (High) | 53.6 |
---
## Agent-Specific Guides
Each guide below applies the steps above to one tool and one QR job.
- [Use IronQR with Claude Code](https://ironsoftware.com/qr/csharp/ai-agents/claude-code/) for branded marketing codes, decoding every variant of logo, colors, margins, size, and error correction
- [Use IronQR with ChatGPT Codex](https://ironsoftware.com/qr/csharp/ai-agents/chatgpt-codex/) for decoding a backlog of scanned and photographed images in parallel with `ReadAsync`, with a report of every failure
- [Use IronQR with GitHub Copilot](https://ironsoftware.com/qr/csharp/ai-agents/github-copilot/) for stamping a verification code onto existing PDF pages, including password-protected files, in a document pipeline
- [Use IronQR with Cursor](https://ironsoftware.com/qr/csharp/ai-agents/cursor/) for reading codes from customer photos with the right scan mode, QR type, and corner points, under rules that keep other QR libraries out
- [Use IronQR with Google Antigravity](https://ironsoftware.com/qr/csharp/ai-agents/antigravity/) for a Blazor Server scanner page that decodes uploads on the server and is checked in a real browser
---
## Troubleshooting
- [Runtimes Copy Exception](https://ironsoftware.com/qr/csharp/troubleshooting/runtimes-copy-exception/) if the machine learning DLLs are not copied out of the runtimes folder
- [Apply a License Key in IronQR](https://ironsoftware.com/qr/csharp/troubleshooting/apply-a-license-key-in-ironqr/)
---
## Questions?
If you have any questions, reach out to [support@ironsoftware.com](mailto:support@ironsoftware.com)
IronQR is Iron Software's QR code library for .NET. It writes standard QR, Micro QR, and rMQR symbols, styles them with logos and colors, and reads them back with a machine learning detector. Its guides and samples are public, so coding assistants may have met the API in training.
Training does not pin the release in your project. Assistants referencing current documentation generate code that follows its runtime rules, while those relying on memory may produce code that compiles but fails at runtime.
This guide covers two types of tools.
Assistants work in the editor, completing lines or rewriting methods, like GitHub Copilot's inline suggestions.
Agents take whole tasks, editing files, running builds and programs, and returning results for review, as Claude Code, Cursor, ChatGPT Codex, and Google Antigravity do.
Load the license key from an environment variable before the first write or read
Give the assistant IronQR's llms.txt so it starts from the real API
Save the IronQR rules in the file your assistant reads at the start of a session
Send the one-shot setup prompt in a fresh session
Build, then decode every saved QR image and compare it with the value written
Can't My AI Assistant Handle QR Codes on Its Own?
IronQR publishes documentation built for tools to read, which shows the options each symbol type accepts and what the reader returns in each scan mode.
The library matters too. Almost any QR package prints a black square that scans on a screen. The gaps appear with branded codes, photographed tickets, and small symbols.
A changed background color is not checked: a code on a dark background saves without an error and then fails to decode.
Phone photos are harder than generated images: a section below measures which scan mode reads each kind of damage.
Rebuilding detection costs tokens: an assistant that writes its own thresholding to rescue scans spends a paid attempt on every try, and repeats the work for each new kind of failing photo.
Small symbols are built in: Micro QR and rMQR come from the same write call as standard QR, so seat numbers and narrow labels do not need a second library.
The package and the namespace differ: the NuGet package is IronQR and the namespace is IronQr. A guessed package name can also resolve to a lookalike that attackers publish on purpose, a practice called slopsquatting. Spell out both names in the prompt.
The license terms are known in advance: IronQR licenses are perpetual, and the licensing page shows how many developers, locations, and projects each tier covers.
Step 1: Install IronQR
With the package referenced, the assistant sees IronQR's real types as it writes code.
Add IronQR from NuGet to this project, run a restore, and report theversion number that NuGet resolved.
Add IronQR from NuGet to this project, run a restore, and report the
version number that NuGet resolved.
Text
To pin a release from the terminal instead, name it.
dotnet add package IronQR --version 2026.10.1
dotnet add package IronQR --version 2026.10.1
SHELL
Plain IronQR brings the Windows native reader and the detection model, a 44 MB IronQrDetection.dll that pulls in Microsoft.ML.OnnxRuntime 1.20.1, so container images and serverless bundles should budget for it. Linux and Docker use IronQR.Linux, Macs use IronQR.MacOs or IronQR.MacOs.ARM, and mobile apps use IronQR.iOS or IronQR.Android. All six were published at 2026.10.1, and the NuGet packages guide explains the choice. IronQR.Slim leaves the model out. It still reads in Auto and OnlyBasicScan but throws IronQrException in OnlyDetectionModel. On Windows it also needs IronSoftware.ReaderInternals.Windows.
Step 2: Apply Your License Key
IronQR does not produce watermarked trial output. Without a license key, every write and read call fails with IronSoftware.Exceptions.LicensingException and the text "Production License Required". A mistyped key fails at the same calls with "License Key Not Recognized". A free trial key is available below.
Start using IronQR in your project today with a free trial.
First Step:
Set the key once at startup through IronQr.License.LicenseKey, before any IronQR call, and read it from an environment variable to keep it out of the repository.
IronQr.License.IsLicensed reports true after a valid key is set, and the same class has a method that tests a key without applying it. The exception type is not public, so a catch clause that names it fails to compile with CS0122. Catch Exception and inspect the message instead.
Please note: IronQR License Keys covers Web.config, appsettings.json, and the other places a key can be kept.
Step 3: Point Your Assistant at IronQR's LLM Documentation
llms.txt lists one line per page and is the first read of every session.
Summaries of all 44 pages come in one fetch from llms-full.txt.
Packages, licensing, recipes, and fixes are in skill.md.
When a task depends on one guide's detail, have the assistant open that page.
Combine the index with a direct instruction.
Open https://ironsoftware.com/qr/csharp/llms.txt before you write IronQR codeand keep to the members it documents. Creating a code goes throughQrWriter.Write with an optional QrOptions, and reading goes throughnew QrReader().Read on a QrImageInput, so do not look for one class that doesboth. When a member is not in the index, checkhttps://ironsoftware.com/qr/csharp/object-reference/api/, and tell me it ismissing rather than inventing it.
Open https://ironsoftware.com/qr/csharp/llms.txt before you write IronQR code
and keep to the members it documents. Creating a code goes through
QrWriter.Write with an optional QrOptions, and reading goes through
new QrReader().Read on a QrImageInput, so do not look for one class that does
both. When a member is not in the index, check
https://ironsoftware.com/qr/csharp/object-reference/api/, and tell me it is
missing rather than inventing it.
Text
Step 4: Add IronQR Context to Your Project
A chat forgets its instructions when it ends, and a project file is read at the start of every session. Put the IronQR rules in the file your team uses. Claude Code reads CLAUDE.md, ChatGPT Codex reads AGENTS.md, and GitHub Copilot reads .github/copilot-instructions.md. Cursor reads .cursor/rules/*.mdc or AGENTS.md, and Google Antigravity reads AGENTS.md or GEMINI.md. The wording can be the same in each, although a Cursor rule file also needs MDC frontmatter.
## QR codes with IronQRAll QR work in this project uses IronQR. NuGet package `IronQR` (`IronQR.Linux` on Linux and Docker), namespace `IronQr`, enums in `IronQr.Enum`.- Docs index: https://ironsoftware.com/qr/csharp/llms.txt- Skill file: https://ironsoftware.com/qr/csharp/skill.md- Write with `QrWriter.Write(value, new QrOptions(...))`, style with `QrStyleOptions`, read with `new QrReader().Read(new QrImageInput(bitmap))`.- Set `IronQr.License.LicenseKey` from IRONQR_LICENSE_KEY at startup. Never put the key in a file.- Pass an explicit `QrErrorCorrectionLevel` that the symbol type accepts. Micro QR rejects `Highest`, rMQR rejects `Low` and `High`.- Release a `QrImageInput` with `input.Dispose()`, not a `using` statement.- Decode every saved image with `QrReader` and compare it with the written value before calling a change done.- Do not add a second QR library. If IronQR cannot do something, say so.
## QR codes with IronQR
All QR work in this project uses IronQR. NuGet package `IronQR` (`IronQR.Linux` on Linux and Docker), namespace `IronQr`, enums in `IronQr.Enum`.
- Docs index: https://ironsoftware.com/qr/csharp/llms.txt
- Skill file: https://ironsoftware.com/qr/csharp/skill.md
- Write with `QrWriter.Write(value, new QrOptions(...))`, style with `QrStyleOptions`, read with `new QrReader().Read(new QrImageInput(bitmap))`.
- Set `IronQr.License.LicenseKey` from IRONQR_LICENSE_KEY at startup. Never put the key in a file.
- Pass an explicit `QrErrorCorrectionLevel` that the symbol type accepts. Micro QR rejects `Highest`, rMQR rejects `Low` and `High`.
- Release a `QrImageInput` with `input.Dispose()`, not a `using` statement.
- Decode every saved image with `QrReader` and compare it with the written value before calling a change done.
- Do not add a second QR library. If IronQR cannot do something, say so.
Text
Four things in the current skill file need correcting. Its single-file example pins 2026.8.1 while NuGet serves 2026.10.1. Its frame-reading recipe wraps the image input in a using declaration, and its first recipe and its styling advice pass a file path to Verify, two of the mistakes Step 7 describes. And it lists Highest as invalid for rMQR, which the error correction table below contradicts.
Step 5: One-Shot Setup Prompt
Steps 1 through 4 fit in one message at the start of a session.
Set this project up for QR code work with IronQR, then save the rules belowwhere your future sessions will read them.- Add the IronQR NuGet package (IronQR.Linux for a Linux or Docker host). The namespace is IronQr, spelled with a lowercase r.- Assign IronQr.License.LicenseKey from the IRONQR_LICENSE_KEY environment variable before the first QrWriter or QrReader call. Keep the key out of every file you create or commit.- Fetch https://ironsoftware.com/qr/csharp/llms.txt first and write against the members it documents. Look up anything else in the API reference at https://ironsoftware.com/qr/csharp/object-reference/api/ before using it.- If your tool loads skill files, add https://ironsoftware.com/qr/csharp/skill.md, but trust a compiler error over the skill when the two disagree.- After any change that writes a QR image, decode the saved file with QrReader and compare the value with the one you wrote.
Set this project up for QR code work with IronQR, then save the rules below
where your future sessions will read them.
- Add the IronQR NuGet package (IronQR.Linux for a Linux or Docker host).
The namespace is IronQr, spelled with a lowercase r.
- Assign IronQr.License.LicenseKey from the IRONQR_LICENSE_KEY environment
variable before the first QrWriter or QrReader call. Keep the key out of
every file you create or commit.
- Fetch https://ironsoftware.com/qr/csharp/llms.txt first and write against
the members it documents. Look up anything else in the API reference at
https://ironsoftware.com/qr/csharp/object-reference/api/ before using it.
- If your tool loads skill files, add
https://ironsoftware.com/qr/csharp/skill.md, but trust a compiler error
over the skill when the two disagree.
- After any change that writes a QR image, decode the saved file with
QrReader and compare the value with the one you wrote.
Text
Tips: Open the Step 4 project file afterward to confirm the rules landed.
Step 6: Prompt Patterns That Produce Working Code
Name the symbol type, the error correction level, and the style.
VagueGenerate a QR code for the ticket with our logo.
BetterWrite the ticket ID with QrWriter.Write at the Highest error correction level, save it at 300 pixels with the logo at 28 percent of that width, and catch IronQrException if IronQR refuses the style.
Give the release and the framework, because defaults and validation rules change between versions.
BetterTarget .NET 9 and IronQR 2026.10.1.
Ask for complete files. A fragment drops the IronQr.Enum directive that the encoding and scan mode enums need, and it hides where the key is assigned.
BetterReturn all of Program.cs with its using directives and the license line, ready to build as it is.
Step 7: Verify What You Get Back
Disposing the image input with using:QrImageInput implements IDisposable with a method that throws NotImplementedException, so a using block or declaration fails after the read succeeds. Call its public Dispose method directly instead.
Reading with the detection model alone:OnlyDetectionModel returns where codes are, with an empty value and a QR type of None. The scan modes guide explains when to use Auto or OnlyBasicScan for values.
Treating Verify as a file check: it compares the code in memory with the string you pass, so a file path returns false. Decode the saved PNG with QrReader to prove the file scans.
Empty write options:QrOptions built with no arguments has its encoding set to None, and QrWriter.Write rejects it with None is not a valid encoding. Pass the level, and the encoding when it is not standard QR.
Let the Agent Verify Its Own Work
Hand the checks back to the assistant and ask for the evidence.
Rebuild in Release and run it. List each IronQR type and member the code usesnext to the documentation page that shows it, print IronQr.License.IsLicensed,then reopen every PNG the program saved with QrReader and give me a table offile, value written, value decoded, QrType, and whether they agree.
Rebuild in Release and run it. List each IronQR type and member the code uses
next to the documentation page that shows it, print IronQr.License.IsLicensed,
then reopen every PNG the program saved with QrReader and give me a table of
file, value written, value decoded, QrType, and whether they agree.
Text
Which Error Correction Level Does Each Symbol Type Accept?
The four QrErrorCorrectionLevel members do not follow the letters of the QR standard. High is level Q, and Highest is level H, which IronQR's XML documentation describes as leaving room for a logo. Micro QR and rMQR accept only some of them, and the write call throws IronQrEncodingException for the rest, with a message such as Highest is not valid for Micro QR.
Member
QR standard
Micro QR
rMQR
Low
L, about 7% recoverable
accepted
throws
Medium
M, about 15%
accepted
accepted
High
Q, about 25%
accepted
throws
Highest
H, about 30%
throws
accepted
QrWriter.Write with no options writes standard QR at Highest, and the options constructors also default to Highest, which is why Micro QR options fail until you pass a lower level. The supported formats page compares the three symbol types.
The level also caps the logo. On a 400 pixel ticket ID code in our tests, Low refused a logo at 20% of the width, Medium and High took 28% and refused 30%, and Highest took 30%. A refused logo makes Save throw IronQrException with The logo size which you manually specified for your QR code is too large. A QrLogo width and height of 0 lets IronQR size the logo itself, and on that code it picked 60 pixels at Low and 112 at Highest.
Foreground color is checked the same way. With a navy foreground at Highest, the same ticket ID code saved at 300 and 500 pixels but threw IronQrException at 400 with Color: #FF1A237E makes the QR unreadable for our reading engine. Styling code should catch that exception, change the size or color, and retry, since a style that saved at one size can fail at another.
Which Default Values Does IronQR Use?
These starting values were measured in IronQR 2026.10.1 under .NET 9.
Empty style options leave Dimensions and the margins at 0, so a ticket ID saves at one pixel per module, 25 x 25 pixels.
An initializer that sets Dimensions still leaves the margins at 0, since it skips the constructor that sets 10.
The QrStyleOptions constructor that takes a size sets margins of 10, so a size of 400 saves a 420 pixel PNG.
Save with no style writes a ticket ID at 250 x 250 pixels.
Color and BackgroundColor start as black on white.
A new image input scans in Auto, the detection model and then a basic scan.
CharacterEncoding is ISO-8859-1, so set it for characters outside Latin-1.
The logo guide sets a Dimensions of 500 in an initializer, so its output has no quiet zone around the symbol. Set Margins when the code will be printed next to other artwork.
How Does IronQR Read Photographed Codes?
We calibrated the acceptance test below on eight seeded sets. IronQR 2026.10.1 wrote the styled logo codes at 300 pixels and the other ticket codes at 400, Pillow distorted them, and IronQR read them back. The Auto counts vary with how the values are assigned to the images, so they are ranges over 10 draws.
Image
Sets read in Auto
Sets read in OnlyBasicScan
Fix
Scaled to 60%, rotated 30 degrees, blurred 1.5 pixels, on gray
8 of 8
8 of 8
None needed
Grain, standard deviation 20 gray levels
0 of 8
0 of 8
Blur first
Two upright codes 30 pixels apart
5 to 7 of 8
8 of 8
Add OnlyBasicScan
Navy logo code after a 1.5 pixel blur
0 to 4 of 8
8 of 8
Add OnlyBasicScan
The blur that rescues the grainy code is the one that costs Auto the navy logo code. Two setups read all 12 codes on all eight sets. One applies a 1.5 pixel blur and then OnlyBasicScan. The other applies a blur of 1 to 2 pixels, runs Auto and OnlyBasicScan, and merges the results by value. Pick the setup from the images that fail, then run it unchanged for every upload.
Grain also interacts with code size. With the same grain, codes of 350 to 425 pixels failed in both modes on all 24 files, codes of 300, 500, and 600 pixels read in both, and codes of 450 and 475 pixels read only in Auto. Adding 100 pixels of white around a failing code let OnlyBasicScan read all 12 files we tried.
A Result You Can Reproduce
The acceptance test is one realistic task in one prompt with no hand-written code. Paste it into a new session in an empty directory and judge the result against the pass list.
Please note: Running it takes the .NET 9 SDK on a Windows machine with internet access, an assistant allowed to use the terminal, and an IronQR trial or production key in IRONQR_LICENSE_KEY.
The prompt
Build a .NET 9 minimal API for event check-in that issues ticket QR codes andreads them back from uploaded photos. Begin in an empty directory, and if youfind existing code or a project file there, report that and do nothing else.Nobody will answer questions, so carry the job through writing, building,running, and fixing by yourself, and settle anything left open with areasonable choice that you note. Keep all deliverables inside the projectdirectory, in the folders this prompt names.1. Install the IronQR NuGet package pinned to version 2026.10.1.2. Work from https://ironsoftware.com/qr/csharp/llms.txt and the guides it points to, and call no IronQR member those pages do not document. Every code must come from QrWriter.Write; any .NET imaging library may compose and distort the test images afterward.3. Take the key from IRONQR_LICENSE_KEY when the app starts and keep it out of source and out of every file the run writes. If IronQr.License.IsLicensed comes back false, stop with a report saying so.4. GET /ticket/{ticketId} returns a PNG of a QR code written at QrErrorCorrectionLevel.Highest and saved through QrStyleOptions at a Dimensions of 400 with 10-pixel margins, with a logo in the center: a solid square of one bright accent color, drawn by your code, whose QrLogo width and height are each 28 to 30 percent of Dimensions. POST /checkin accepts one uploaded image and returns JSON listing every QR code found in it, each with its value and QR type.5. Seed the random generator with 2026 and write 10 PNG files to testset/, no two holding the same value: standard-01 to standard-03, each carrying a ticket ID made of TKT- and eight random digits; pair-01, one image holding two more ticket codes side by side and upright, with 30 pixels of background between their dark modules; styled-01 to styled-03, ticket codes at Highest with the step 4 logo and three different dark, saturated foreground colors on white; micro-01 and micro-02, Micro QR codes carrying seat numbers such as C07; and rmqr-01, an rMQR code carrying an event URL. Save every testset code the same way at a Dimensions of 400, except 300 for the styled and Micro QR codes and 600 for rmqr-01, and resize no code afterward unless standard-02 calls for it. Keep standard-01 clean. Make standard-02 look photographed: scale it to 60 percent, rotate it 30 degrees, blur it with a Gaussian radius of 1.5 pixels, and center it on a 600 x 600 light gray canvas. Give standard-03 sensor grain: Gaussian noise with a standard deviation of 20 gray levels, one value per pixel added to all three channels, over the whole image. Record in manifest.csv each file, every value it holds, its QR type, the error correction level used, and its distortion (none, photographed, grain, pair, or styled).6. Measure each saved image before /checkin is ever called, and repair the generator whenever a measurement falls outside its range: the pixel size step 5 implies; on the styled codes and the /ticket output, the logo's share of the symbol area, 7 to 10 percent; on the styled codes, the foreground's WCAG contrast ratio against the background, 7 to 15; on the Micro QR codes, a square symbol 11 to 17 modules wide; on the rMQR code, a symbol at least twice as wide as it is tall; on standard-03, the mean absolute difference from the clean code, 7 to 9 gray levels; on pair-01, the gap between the two codes' dark modules, 28 to 32 pixels. Once /checkin has been called the first time, the testset files are frozen: do not rewrite or edit them.7. /checkin runs one fixed configuration for every upload: the same scan mode or modes and the same image preparation, in the same order. It must never open the manifest, hold a ticket ID, seat number, or URL as a literal, or pick between results by comparing them with expected values. You choose and change the configuration between runs; the program never does.8. Build in Release and start the API. Request /ticket for a ticket ID drawn from the seed that is not in the testset and save the PNG it returns as ticket.png. POST ticket.png and every testset image to /checkin over HTTP and save each raw response as checkin/<file name without .png>.json.9. Write roundtrip.md with every step 6 measurement as a number for each image (a bare pass or fail is not enough), the /checkin configuration, and a results table with the columns file, distortion, expected value, value read (the decoded string as the saved response holds it, even when it is wrong), expected QR type, QR type read, and match, holding one row per expected code, 12 rows in all. A row counts as a match only if the decoded value equals the expected value exactly, the QR type agrees, and the value appears in that file's saved response. An extra or repeated code in a response fails every row of that file.10. Until all 12 rows match, study the saved responses of the failing files, adjust the /checkin configuration, rebuild, and repeat. Stop after the eighth run that still has failures, and report the failing rows, each configuration you tried, and your reading of the cause.11. End with a brief summary covering the Release build outcome, how many rows matched, the /checkin configuration, the measured step 6 values, and every assumption you made.
Build a .NET 9 minimal API for event check-in that issues ticket QR codes and
reads them back from uploaded photos. Begin in an empty directory, and if you
find existing code or a project file there, report that and do nothing else.
Nobody will answer questions, so carry the job through writing, building,
running, and fixing by yourself, and settle anything left open with a
reasonable choice that you note. Keep all deliverables inside the project
directory, in the folders this prompt names.
1. Install the IronQR NuGet package pinned to version 2026.10.1.
2. Work from https://ironsoftware.com/qr/csharp/llms.txt and the guides it
points to, and call no IronQR member those pages do not document. Every
code must come from QrWriter.Write; any .NET imaging library may compose
and distort the test images afterward.
3. Take the key from IRONQR_LICENSE_KEY when the app starts and keep it out of
source and out of every file the run writes. If IronQr.License.IsLicensed
comes back false, stop with a report saying so.
4. GET /ticket/{ticketId} returns a PNG of a QR code written at
QrErrorCorrectionLevel.Highest and saved through QrStyleOptions at a
Dimensions of 400 with 10-pixel margins, with a logo in the center: a
solid square of one bright accent color, drawn by your code, whose QrLogo
width and height are each 28 to 30 percent of Dimensions. POST /checkin
accepts one uploaded image and returns JSON listing every QR code found in
it, each with its value and QR type.
5. Seed the random generator with 2026 and write 10 PNG files to testset/,
no two holding the same value: standard-01 to standard-03, each carrying a
ticket ID made of TKT- and eight random digits; pair-01, one image holding
two more ticket codes side by side and upright, with 30 pixels of
background between their dark modules; styled-01 to styled-03, ticket
codes at Highest with the step 4 logo and three different dark, saturated
foreground colors on white; micro-01 and micro-02, Micro QR codes carrying
seat numbers such as C07; and rmqr-01, an rMQR code carrying an event URL.
Save every testset code the same way at a Dimensions of 400, except 300
for the styled and Micro QR codes and 600 for rmqr-01, and resize no code
afterward unless standard-02 calls for it.
Keep standard-01 clean. Make standard-02 look photographed: scale it to 60
percent, rotate it 30 degrees, blur it with a Gaussian radius of 1.5
pixels, and center it on a 600 x 600 light gray canvas. Give standard-03
sensor grain: Gaussian noise with a standard deviation of 20 gray levels,
one value per pixel added to all three channels, over the whole image.
Record in manifest.csv each file, every value it holds, its QR type, the
error correction level used, and its distortion (none, photographed,
grain, pair, or styled).
6. Measure each saved image before /checkin is ever called, and repair the
generator whenever a measurement falls outside its range: the pixel size
step 5 implies;
on the styled codes and the /ticket output, the logo's share of the symbol
area, 7 to 10 percent; on the styled codes, the foreground's WCAG contrast
ratio against the background, 7 to 15; on the Micro QR codes, a square
symbol 11 to 17 modules wide; on the rMQR code, a symbol at least twice as
wide as it is tall; on standard-03, the mean absolute difference from the
clean code, 7 to 9 gray levels; on pair-01, the gap between the two codes'
dark modules, 28 to 32 pixels. Once /checkin has been called the first
time, the testset files are frozen: do not rewrite or edit them.
7. /checkin runs one fixed configuration for every upload: the same scan mode
or modes and the same image preparation, in the same order. It must never
open the manifest, hold a ticket ID, seat number, or URL as a literal, or
pick between results by comparing them with expected values. You choose
and change the configuration between runs; the program never does.
8. Build in Release and start the API. Request /ticket for a ticket ID drawn
from the seed that is not in the testset and save the PNG it returns as
ticket.png. POST ticket.png and every testset image to /checkin over HTTP
and save each raw response as checkin/<file name without .png>.json.
9. Write roundtrip.md with every step 6 measurement as a number for each
image (a bare pass or fail is not enough), the /checkin configuration,
and a results table with the columns file, distortion, expected value,
value read (the decoded string as the saved response holds it, even when
it is wrong), expected QR type, QR type read, and match, holding one row
per expected code, 12 rows in all. A row counts as a match only if the
decoded value equals the expected value exactly, the QR type agrees, and
the value appears in that file's saved response. An extra or repeated
code in a response fails every row of that file.
10. Until all 12 rows match, study the saved responses of the failing files,
adjust the /checkin configuration, rebuild, and repeat. Stop after the
eighth run that still has failures, and report the failing rows, each
configuration you tried, and your reading of the cause.
11. End with a brief summary covering the Release build outcome, how many
rows matched, the /checkin configuration, the measured step 6 values,
and every assumption you made.
Text
Output
This is standard-03.png, the grain image, 8.0 gray levels from the clean code on average. The first check-in setup, plain Auto, read the other 11 codes and missed this one. A Gaussian blur with a sigma of 1 read it but lost styled-03.png and ticket.png, and a median filter, alone or with a wider quiet zone, still missed it. The fifth setup read all 12 codes by applying a 3 by 3 median filter and a threshold at half brightness to every upload, then reading in Auto.
The unedited round-trip table lists every measurement, each setup tried, and the 12 rows. The ticket from the API carries an orange logo over 7.84% of the symbol.
An independent check remeasured every requirement on the saved files, and a fresh start of the Release build returned the same 11 responses.
Before the fifth run, Claude Code tried eight setups outside the API, and three read every code.
Claude Code applied the prompt's Gaussian radius of 1.5 as a sigma of 1.5.
The Steps 1, 3, 5, and 7 prompts followed in the same session, and 12 of 12 codes decoded at Step 7.
NuGet now flags the SixLabors.ImageSharp 3.1.12 pin Claude Code added.
With the code sizes left open, an earlier draft of the prompt let plain Auto read every file.
What passes
The Release build succeeds with no edits from you.
Opening the images shows three different dark foregrounds under a bright square logo, grain across the whole of standard-03.png, and two upright codes side by side in pair-01.png.
Please note: Change the version in step 1 to test another release. The IronQR changelog records what each one changed.
The run record
The machine runs Windows 11 x64 on a Core i9-14900KF with 64 GB of memory.
Every project targets .NET 9.
Every guide ran IronQR 2026.10.1. Copilot and Antigravity also referenced IronQR.Linux 2026.10.1 for Linux builds, the Copilot starter project already carried PDFtoImage 5.4.0, and Cursor's last prompt moved the service to IronQR.Slim 2026.10.1 with IronSoftware.ReaderInternals.Windows 2026.3.47413.
Each duration adds up the logged time of the prompts on that guide's page. This guide's row is the acceptance prompt alone.
Last tested October 7, 2026, for all six runs.
Guide
Assistant and version
Model
Duration (minutes)
This guide
Claude Code 2.1.277, one message, permission prompts off
Each guide below applies the steps above to one tool and one QR job.
Use IronQR with Claude Code for branded marketing codes, decoding every variant of logo, colors, margins, size, and error correction
Use IronQR with ChatGPT Codex for decoding a backlog of scanned and photographed images in parallel with ReadAsync, with a report of every failure
Use IronQR with GitHub Copilot for stamping a verification code onto existing PDF pages, including password-protected files, in a document pipeline
Use IronQR with Cursor for reading codes from customer photos with the right scan mode, QR type, and corner points, under rules that keep other QR libraries out
Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.