QRdx
HelpGuidesDevelopersReact librarySelf-hosting

AI art API

Paint a QR code into AI artwork with one REST call or MCP tool. QRdx checks that every image scans, and each one uses your workspace's monthly AI art images.

POST https://api.qrdx.dev/v1/art paints a QR code into AI artwork from a description and returns the image. It's the same AI QR art as the playground's Art tab and the studio: OpenAI's GPT Image 2 paints the picture, then QRdx checks that it scans to your content before you get it. Where the model's image doesn't scan as drawn, QRdx strengthens the code just enough, on the model's own pixels.

It needs an API key with the codes:write scope (Full access keys have it). Each image uses one of the monthly AI art images of the key's workspace, the same allowance the app uses.

curl https://api.qrdx.dev/v1/art \
  -H "Authorization: Bearer $QRDX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "https://qrdx.dev", "prompt": "a koi pond at dusk, ink and watercolor"}' \
  --max-time 90 -o art.json

A call takes about 15 to 45 seconds in code mode, about 25 to 45 in photo mode and about 40 to 55 in scene mode, which makes its picture first. Give your HTTP client a timeout of at least 60 seconds. A scene that runs out of time answers 504 AI_ART_TIMEOUT and uses no image: try again, or use code mode.

Encode a link or a dynamic code

Send exactly one of these:

  • text: the link or text the code holds, up to 300 characters. The art is a picture, so its content can't change after you print it.
  • code: the id of one of the workspace's dynamic codes. The art encodes the code's short link, so you can change where it goes after printing, and its scans show in analytics. A code from another workspace, or one in the trash, is a 404.
curl https://api.qrdx.dev/v1/art \
  -H "Authorization: Bearer $QRDX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code": "cm5code0spring0menu00001", "prompt": "a bistro chalkboard menu on a brick wall", "mode": "scene"}' \
  --max-time 90

Get a code's id from GET /v1/codes or when you create one.

Request

FieldDefaultDescription
textWhat the code encodes. Send this or code
codeA dynamic code's id, in place of text
promptwritten for youThe artwork to paint, in plain words; see A prompt written for you
modecodeHow the code sits in the art; see Modes
styleA quick look's id, combined with your prompt; see Quick looks
negativePromptWhat to keep out of the picture
visibility50QR visibility, 0 to 100: higher shows the code more clearly, lower favors the picture
creativity450 follows the prompt literally, 100 interprets it freely
seedrandomSend a seed from an earlier response for a similar image
referenceA reference image for colors and shapes, such as a logo or a palette
photoPhoto mode only: the picture to paint the code into

reference and photo are PNG or JPEG data: URLs (data:image/jpeg;base64,…). Downsize a reference to about 512 px on its longest side (at most 600 KB), and crop a photo square at about 1024 px (at most 1 MB), the size the art is made at. They go to the model and are discarded: QRdx never stores or logs them. Larger images are refused with 413 AI_ART_IMAGE_TOO_LARGE.

The API reference has the full schema.

Modes

modeWhat you get
codeThe code is the whole picture: your artwork painted into its modules, with plain finder squares and a light quiet zone around it. Scans most reliably
sceneA picture is painted from the description first, then the code is painted into its middle, so the picture runs right up to and through the code, with the modules made of its colors and light
photoThe same with your own photo as the picture: it keeps its subject, colors and light around and through the code. Send the photo with this mode only

Quick looks

A quick look is a ready-made style, such as a medium or a mood, that QRdx adds to your own prompt: "a koi pond in the rain" with "style": "watercolor" paints the koi pond as a watercolor. Send its id as style; any other value is a 400 VALIDATION_ERROR. The looks are the ones offered as chips in the AI art studio and the playground's Art tab, and they work in every mode.

styleLook
watercolorWatercolor
oil-paintingOil painting
animeAnime
cartoonCartoon
pixel-artPixel art
pop-artPop art
charcoalCharcoal
inkInk
cyberpunkCyberpunk
fantasyFantasy
photographicPhotographic
low-polyLow poly
papercutPapercut

A prompt written for you

prompt is optional. Leave it out and QRdx first writes one for the mode, style and photo you sent: one concrete scene with a subject, a setting and the light, or in photo mode a description of what's in your photo so the art keeps it. Writing it uses no extra AI art image. The response then includes what was written as writtenPrompt, so you can send it again, edited, next time. If the writing fails, you get 502 AI_ART_DESCRIBE_FAILED and no image is used.

Response

{
  "data": {
    "imageUrl": "data:image/png;base64,iVBORw0KGgo…",
    "width": 1024,
    "height": 1024,
    "seed": 2841337190,
    "mode": "code",
    "blend": "least",
    "blendStrength": 0.35,
    "text": "https://qrdx.dev/q/aB3dE5f",
    "code": { "id": "cm5code0spring0menu00001", "shortLink": "https://qrdx.dev/q/aB3dE5f" },
    "visibility": 50,
    "creativity": 45
  },
  "credits": {
    "plan": "pro",
    "limit": 30,
    "used": 7,
    "remaining": 23,
    "pooled": false,
    "resetsAt": "2026-02-01T00:00:00.000Z"
  }
}
  • imageUrl is a 1024 px square PNG as a data: URL. QRdx doesn't keep a copy, so save it.
  • text is exactly what the image scans to. QRdx decoded it before answering.
  • blend says how the image was made to scan: none (the model's image as drawn), least (the finder squares, quiet zone and modules strengthened just enough, on the model's image) or image-qr (redrawn as an Image QR code, the last resort). blendStrength goes from 0 (as drawn) to 1 (Image QR).
  • writtenPrompt is there only when you left out prompt: the description QRdx wrote for you.
  • credits is the workspace's allowance after this image.

To get the PNG itself instead of JSON, add ?format=png or send Accept: image/png. The seed, mode, blend and images left then come as the X-QRdx-Seed, X-QRdx-Mode, X-QRdx-Blend, X-QRdx-Blend-Strength and X-QRdx-Credits-Remaining headers.

curl "https://api.qrdx.dev/v1/art?format=png" \
  -H "Authorization: Bearer $QRDX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "https://qrdx.dev", "prompt": "a lighthouse on a cliff, woodcut print"}' \
  --max-time 90 -o art.png

Credits

The API draws on the same monthly AI art images as the app, counted for the workspace the key belongs to. Free, Pro and Business each include a number of images a month, and Business shares them across the whole team; Plans and limits has the numbers. They reset on the 1st of each month (UTC).

  • A call that fails, or whose image can't be made to scan, uses no image.
  • When the month's images are used, the API answers AI_ART_CREDITS_EXHAUSTED: 402 on Free and Pro, where an upgrade adds more, and 429 on Business.
  • Each person can make at most 25 images a day, on top of the monthly allowance (429 AI_ART_DAILY_LIMIT).
  • Each person can start up to 12 images a minute.
  • Each call also counts toward the workspace's daily API quota and the per-minute limit on writes (Rate limits).

Errors

Errors have the API's usual shape (code, message, status); Errors lists them all. The ones specific to AI art:

StatuscodeWhat to do
400AI_ART_TEXT_TOO_LONGShorten text, or send a dynamic code's code
402AI_ART_CREDITS_EXHAUSTEDWait for the 1st of the month, or upgrade
413AI_ART_IMAGE_TOO_LARGEDownsize photo or reference
429AI_ART_CREDITS_EXHAUSTEDBusiness: wait for the 1st of the month
429AI_ART_DAILY_LIMITTry again tomorrow (UTC)
502AI_ART_FAILEDThe model failed or declined the prompt. Try again or reword it
502AI_ART_UNSCANNABLETry again with a higher visibility or another seed
502AI_ART_DESCRIBE_FAILEDNo prompt was sent and writing one failed. Try again or send your own
503AI_ART_BUSYThe model is busy. Wait a minute and try again
503AI_NOT_CONFIGUREDAI art isn't set up on this server (self-hosted)
504AI_ART_TIMEOUTThe model took too long (in scene mode, the picture left too little time to paint the code). No image is used. Try again, or use code mode

None of the 5xx errors uses an image.

MCP

With a QRdx API key on the connection, the MCP server has a generate_ai_art tool. It takes the same fields as the request body and returns the PNG, what it scans to and the images left this month. Ask your assistant in plain words:

Make AI QR art for my code cm5code0spring0menu00001: a bistro chalkboard menu on a brick wall, as a scene.

Without a key, the tool answers with how to add one. The call takes up to a minute, like the REST API.

Self-hosting

AI art runs through Vercel AI Gateway. On your own instance, set AI_GATEWAY_API_KEY; without it, POST /v1/art and generate_ai_art answer 503 AI_NOT_CONFIGURED.

Last updated on

On this page