API de QR code
O QR code para as suas faturas, num pedido.
Envie o texto ou o link e receba só a imagem do QR code, em PNG ou SVG, pronta para colocar na sua fatura, cupom ou etiqueta. Um código por chamada, nada fica guardado.
Grátis · 1.000 códigos por mês · SVG ou PNG
Pronto em três passos.
Sem cartão, sem instalar nada.
- Entrar com o Google1
Entre com o Google
Grátis, sem cartão e sem instalar nada.
- A sua chave · aparece uma vezqs_live_7hK2…Copiar2
Crie a sua chave
Um clique na aba Desenvolvedor do seu perfil. Guardamos só uma impressão digital dela.
- POST3
Chame e use a imagem
Você recebe só a imagem do código e quantos ainda tem. O documento continua sendo seu.
Veja antes de programar.
Escolha e veja o código sobre um documento de exemplo, no tamanho real. Logo abaixo, o pedido já escrito.
O essencial, num relance.
A chave fica no servidor
Vai no cabeçalho Authorization. Nunca no navegador nem num app.
- 6201.000
1.000 códigos por mês
Recomeça no dia 1. Até 30 chamadas por minuto, um código cada.
A marca aparece sozinha
Um link do WhatsApp leva o logotipo do WhatsApp. Ou escolha a sua, ou nenhuma.
- +52
59 tipos de conteúdo
Os mesmos do editor, com as mesmas regras de validação.
O seu estilo, guardado
Desenhe no perfil e use pelo id, ou escreva no próprio pedido.
- 400 · content.ssid: required429 · quota-exceeded500 · render-failed
Erros que dizem o quê
Um código para o programa, uma frase para quem lê. Erro não gasta cota.
Três endereços, e mais nada.
Todos em https://api.qrsensei.com, com a chave no cabeçalho Authorization. As respostas são sempre JSON.
POST/v1/qr
Conta 1 código do seu mês (1.000)
Gera um código: envie o conteúdo (e, se quiser, marca, estilo, formato e tamanho) e receba a imagem como data URL, com o que ainda resta.
{ "image": "data:image/png;base64,…", "format": "png", "remaining": 902, "limit": 1000, "resetsAt": "…" }GET/v1/usage
Não conta
Quanto já usou e quanto resta este mês, sem gastar nada. Útil antes de uma remessa grande de faturas.
{ "used": 98, "remaining": 902, "limit": 1000, "resetsAt": "…" }GET/v1/brands
Não conta
As marcas que pode nomear em brand. Público, sem chave, e fica em cache.
{ "brands": ["qrsensei", "instagram", "whatsapp", …], "auto": "auto", "none": "none" }
Perguntas frequentes
É mesmo grátis? Quantos códigos posso gerar?
Sim. Cada conta tem 1.000 códigos por mês, todos os aplicativos juntos, e o contador recomeça no dia 1. O valor atual aparece sempre aqui e no seu perfil.
Vocês guardam o conteúdo dos meus códigos?
Não. O conteúdo vai no corpo do pedido, é desenhado e devolvido; nada dele fica guardado nem nos logs. Do seu lado guardamos só um contador por mês.
PNG ou SVG?
SVG sempre que o seu PDF ou página aceitar: fica nítido em qualquer tamanho e pesa menos. PNG para sistemas que só aceitam imagens; é desenhado no tamanho pedido.
Que tamanho usar numa fatura?
Entre 2 e 3 cm impressos, ou seja, size entre 256 e 384 a 300 dpi. Abaixo de 1,5 cm muitos celulares hesitam. O laboratório mostra o tamanho real sobre o papel.
Posso chamar a API a partir do navegador ou de um app?
Não: a chave ficaria visível para qualquer pessoa. Chame a partir do seu servidor e envie a imagem já pronta para o navegador ou app.
Como coloco a imagem num PDF?
A resposta traz a imagem como data URL. Num gerador de PDF a partir de HTML, use-a direto num <img>. Nas bibliotecas de PDF, tire o base64 depois da vírgula, decodifique e insira como imagem.
O código vai ser sempre legível?
Cada estilo é verificado antes de ser aceito (formas que combinam, contraste mínimo de 4,5:1) e a correção de erro é escolhida para o tamanho e o logotipo. Teste no laboratório: ele lê o código como um celular.
O que acontece se eu passar do limite?
A API responde 429 (quota-exceeded) com a data em que recomeça, e nada é cobrado. Pedidos com erro nunca contam, e GET /v1/usage diz quanto falta.
Posso pôr a minha marca no centro?
Pode usar a marca reconhecida pelo link ("auto"), uma marca do catálogo, a da QrSensei ou nenhuma. Logotipos próprios ainda não entram pela API.
Que pagamentos posso pôr no código?
Qualquer link de pagamento (Stripe, PayPal, Mercado Pago…) como link, e os formatos que os bancos leem direto: SEPA (EPC, na Europa) e PIX (no Brasil).
A API pode mudar e quebrar o meu sistema?
Não sem aviso. Tudo está em /v1: o que funciona hoje continua igual; novidades entram como campos opcionais.
Referência completa: todos os campos, tipos e erros
Gerar um código
Um POST com o conteúdo no corpo. O conteúdo nunca vai no endereço, para não ficar nos logs dos servidores pelo caminho.
curl https://api.qrsensei.com/v1/qr \
-H "Authorization: Bearer $QRSENSEI_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": {
"type": "text",
"text": "FT 2026/118 · 149,90 EUR"
},
"brand": "qrsensei",
"style": {
"color": {
"kind": "solid",
"color": "#18181B"
}
},
"format": "png",
"size": 256
}'Corpo do pedido
| Campo | Valores | O que é |
|---|---|---|
| content | objeto | O que o código guarda, com o seu type. Veja Conteúdos. |
| format | "svg" · "png" | SVG por padrão: nítido em qualquer tamanho e mais leve. PNG para sistemas que só aceitam imagens. |
| size | 128 – 1024 | O lado da imagem em pixels (512 por padrão). Para uma fatura, 256 basta. |
| style | id · objeto | Um dos seus estilos pelo id, ou um estilo escrito na própria chamada. Sem ele: o estilo do aplicativo, ou o padrão da conta. |
| brand | "auto" · "none" · … | O logotipo no centro: reconhecido pelo link (auto), o nome de uma marca, ou nenhum. |
Resposta
{
"image": "data:image/png;base64,iVBORw0KGgo…",
"format": "png",
"remaining": 902,
"limit": 1000,
"resetsAt": "2026-12-01T00:00:00.000Z"
}Os mesmos números vêm nos cabeçalhos X-QrSensei-Remaining, X-QrSensei-Limit e X-QrSensei-Reset.
Autenticação
Cada chamada leva a chave do seu aplicativo no cabeçalho Authorization: Bearer qs_live_….
- A chave aparece uma única vez, quando é criada. Guardamos só uma impressão digital dela: se perder, crie uma nova no seu perfil e a antiga deixa de funcionar.
- Chame a partir do seu servidor, nunca do navegador ou de um app: uma chave no código do front-end pode ser lida por qualquer pessoa.
- Nada dos códigos fica guardado: nem o conteúdo nem as imagens. Só uma contagem por mês.
Conteúdos
Os mesmos tipos do editor, com as mesmas regras. Esta tabela é lida das regras que verificam cada chamada: não tem como ficar desatualizada.
| type | Obrigatórios | Opcionais |
|---|---|---|
| url | url | — |
| text | text | — |
| phone | phone | — |
| subject, body | ||
| sms | phone | message |
| wifi | ssid, password | encryption, hidden |
| vcard | firstName | lastName, organization, title, phone, email, website, address, note |
| raw | payload | — |
| phone | message | |
| telegram | usernameOrHandle | message |
| signal | recipient | message |
| viber | recipient | message |
| mecard | name | organization, phone, email, website, address, note |
| geo | latitude, longitude | label |
| googleMaps | — | latitude, longitude, query |
| waze | — | latitude, longitude, query |
| event | title, start, end | location, description, allDay |
| pix | pixKey, merchantName, merchantCity | amount, txid, description |
| epc | beneficiaryName, iban | bic, amount, reference, remittance |
| paypal | paypalHandleOrEmail | amount, currency, note, paymentUrl |
| mbway | phone | amount, note |
| cryptoWallet | address | currency, amount, network, memo |
| deepLink | uri | — |
| otp | issuer, accountName, secret | otpType, algorithm, digits, period, counter |
| auth | uri | — |
| structuredText | text | — |
| paramUrl | baseUrl | params |
| customContent | content | — |
| links | url | calendarLink · instagram · facebook · linkedin · x · tiktok · youtube · github · spotify · snapchat · pinterest · threads · discord · appStore · googlePlay · appGallery · microsoftStore · pdf · fileDownload · onlineDocument · portfolio · menu · digitalCard · coupon · landingPage · form · review · checkIn · rsvp · catalog · credentialLink |
Um Wi-Fi sem senha leva encryption "nopass". Um campo omitido fica vazio; um campo obrigatório em falta é nomeado no detail do erro.
Estilos
Desenhados no seu perfil, com o código ao vivo ao lado. Cada um tem um id e um deles é o seu padrão; ou escreva o estilo na própria chamada, como style.
{}{ "color": { "kind": "solid", "color": "#18181B" }, "background": { "kind": "transparent" }, "quietZone": 2 }{ "dots": "dots", "finders": "drop", "color": { "kind": "gradient", "type": "linear", "angle": 45, "stops": [ "#0F172A", "#1E40AF" ] }, "background": { "kind": "solid", "color": "#FFF7ED" } }Um estilo só é aceito se for legível: formas que combinam, e tinta mais escura que o papel, com contraste de pelo menos 4,5:1. Um código transparente é verificado contra branco, o papel de uma fatura.
Marcas
"auto" reconhece a marca pelo link (um link do Instagram leva o logotipo do Instagram). Um nome fixa a marca; "none" deixa o centro livre. A lista também vem de GET /v1/brands.
Contra phishing: num link, uma marca fixa só é usada se o link for dessa marca. O logotipo de um banco nunca vai parar num link falso.
- qrsensei
- x
- tiktok
- youtube
- github
- spotify
- telegram
- signal
- viber
- snapchat
- threads
- discord
- messenger
- googleMaps
- appleMaps
- waze
- paypal
- revolut
- wise
- stripe
Limites
| Por mês | 1.000 códigos por conta, todos os aplicativos juntos. Recomeça no dia 1, às 00:00 UTC. |
| Por minuto | 30 chamadas por aplicativo. Um código por chamada: não há geração em massa. |
| Não conta | Chamadas com erro, GET /v1/usage e GET /v1/brands. |
Erros
Sempre um objeto error com code, message e, quando ajuda, detail: o code é para o seu programa, a message para quem lê. Uma chamada com erro não é contada.
| Estado | code | Quando |
|---|---|---|
| 401 | missing-key | Sem chave no cabeçalho Authorization. |
| 401 | invalid-key | A chave não existe ou foi substituída. |
| 400 | invalid-json | O corpo não é JSON. |
| 400 | invalid-request | Um campo fora da lista, ou um valor fora dos limites; o detail diz qual. |
| 400 | invalid-content | Falta um campo obrigatório ou está errado; o detail diz qual. |
| 400 | unknown-brand | Essa marca não está em GET /v1/brands. |
| 422 | brand-mismatch | Uma marca fixa num link que não é dela. |
| 404 | unknown-style | Esse id de estilo não é da sua conta. |
| 403 | not-developer | O modo desenvolvedor está desligado na conta. |
| 403 | suspended | A conta não pode usar a API agora. |
| 413 | too-large | O corpo passa de 16 KB. |
| 429 | quota-exceeded | Os códigos deste mês acabaram. |
| 429 | rate-limited | Chamadas demais neste minuto; o Retry-After diz quanto esperar. |
| 500 | render-failed | Não foi possível desenhar o código. Não conta. |
| 503 | api-off | A API está desligada por um tempo. Não conta. |