API de códigos QR

El código QR para tus facturas, en una llamada.

Envía el texto o el enlace y recibe solo la imagen del código QR, en PNG o SVG, lista para poner en tu factura, ticket o etiqueta. Un código por llamada, no se guarda nada.

Gratis · 1000 códigos al mes · SVG o PNG

POST /v1/qr"text": "FT 2026/118""brand": "qrsensei"
Tu sistemapide el código
QrSenseidevuelve la imagen en ~50 ms
Panadería MaríaPan de molde ×412,40Pedido del mes137,50Total149,90 €
Tu documentopones el código donde quieras

Listo en tres pasos.

Sin tarjeta, sin instalar nada.

  1. Entrar con Google
    1

    Entra con Google

    Gratis, sin tarjeta y sin instalar nada.

  2. Tu clave · se muestra una vezqs_live_7hK2…Copiar
    2

    Crea tu clave

    Un clic en la pestaña Desarrollador de tu perfil. Solo guardamos una huella.

  3. POST
    3

    Llama y usa la imagen

    Recibes solo la imagen del código y cuántos te quedan. El documento sigue siendo tuyo.

Míralo antes de programar.

Elige y mira el código sobre un documento de ejemplo, a su tamaño real. Justo debajo, la llamada ya escrita.

Lo esencial, de un vistazo.

  • La clave se queda en tu servidor

    Va en la cabecera Authorization. Nunca en un navegador ni en una app.

  • 6201000

    1000 códigos al mes

    Vuelve a empezar el día 1. Hasta 30 llamadas por minuto, un código cada una.

  • La marca aparece sola

    Un enlace de WhatsApp lleva el logotipo de WhatsApp. O elige la tuya, o ninguna.

  • +52

    59 tipos de contenido

    Los mismos del editor, con las mismas reglas de validación.

  • Tu estilo, guardado

    Diséñalo en tu perfil y úsalo por su id, o escríbelo en la llamada.

  • 400 · content.ssid: required429 · quota-exceeded500 · render-failed

    Errores que dicen qué pasa

    Un código para tu programa, una frase para quien lo lea. Un error no gasta cuota.

Tres direcciones, nada más.

Todas en https://api.qrsensei.com, con tu clave en la cabecera Authorization. Las respuestas son siempre JSON.

  • POST/v1/qr

    Cuenta 1 código de tu mes (1000)

    Genera un código: envía el contenido (y, si quieres, marca, estilo, formato y tamaño) y recibe la imagen como data URL, con lo que te queda.

    { "image": "data:image/png;base64,…", "format": "png", "remaining": 902, "limit": 1000, "resetsAt": "…" }
  • GET/v1/usage

    No cuenta

    Cuánto has usado y cuánto te queda este mes, sin gastar nada. Útil antes de una tanda grande de facturas.

    { "used": 98, "remaining": 902, "limit": 1000, "resetsAt": "…" }
  • GET/v1/brands

    No cuenta

    Las marcas que puedes nombrar en brand. Público, sin clave y en caché.

    { "brands": ["qrsensei", "instagram", "whatsapp", …], "auto": "auto", "none": "none" }

Preguntas frecuentes

¿De verdad es gratis? ¿Cuántos códigos puedo generar?

Sí. Cada cuenta tiene 1000 códigos al mes, todas las aplicaciones juntas, y el contador vuelve a empezar el día 1. La cifra actual se muestra siempre aquí y en tu perfil.

¿Guardáis el contenido de mis códigos?

No. El contenido va en el cuerpo de la petición, se dibuja y se devuelve; nada se guarda ni queda en los registros. De tu lado solo guardamos un recuento por mes.

¿PNG o SVG?

SVG siempre que tu PDF o página lo acepte: nítido a cualquier tamaño y más ligero. PNG para sistemas que solo aceptan imágenes; se dibuja al tamaño pedido.

¿Qué tamaño usar en una factura?

Entre 2 y 3 cm impresos, es decir, un size de 256 a 384 a 300 ppp. Por debajo de 1,5 cm muchos móviles dudan. El laboratorio muestra el tamaño real sobre el papel.

¿Puedo llamar a la API desde el navegador o una app?

No: la clave quedaría a la vista de cualquiera. Llama desde tu servidor y envía la imagen ya hecha al navegador o a la app.

¿Cómo pongo la imagen en un PDF?

La respuesta trae la imagen como data URL. En un generador de PDF desde HTML, úsala directamente en un <img>. En librerías de PDF, toma el base64 tras la coma, decodifícalo e insértalo como imagen.

¿El código se leerá siempre?

Cada estilo se comprueba antes de aceptarse (formas que combinan, contraste mínimo de 4,5:1) y la corrección de errores se elige según el tamaño y el logotipo. Pruébalo en el laboratorio: lee el código como un móvil.

¿Qué pasa si supero el límite?

La API responde 429 (quota-exceeded) con la fecha en que vuelve a empezar, y no se cobra nada. Las llamadas con error nunca cuentan, y GET /v1/usage te dice cuánto queda.

¿Puedo poner mi marca en el centro?

Puedes usar la marca reconocida por el enlace ("auto"), una del catálogo, la de QrSensei o ninguna. Los logotipos propios aún no se pueden enviar por la API.

¿Qué pagos puede llevar el código?

Cualquier enlace de pago (Stripe, PayPal, Mercado Pago…) como enlace, y los formatos que los bancos leen directamente: SEPA (EPC, en Europa) y PIX (en Brasil).

¿La API puede cambiar y romper mi sistema?

No sin aviso. Todo está en /v1: lo que funciona hoy sigue igual; las novedades llegan como campos opcionales.

Referencia completa: todos los campos, tipos y errores

Generar un código

Un POST con el contenido en el cuerpo. El contenido nunca va en la dirección, para que no quede en los registros de los servidores por el camino.

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
}'

Cuerpo de la petición

CampoValoresQué es
contentobjetoLo que guarda el código, con su type. Ver Contenidos.
format"svg" · "png"SVG por defecto: nítido a cualquier tamaño y más ligero. PNG para sistemas que solo aceptan imágenes.
size128 – 1024El lado de la imagen en píxeles (512 por defecto). Para una factura, 256 basta.
styleid · objetoUno de tus estilos por su id, o un estilo escrito en la llamada. Sin él: el estilo de la aplicación, o el predeterminado de la cuenta.
brand"auto" · "none" · …El logotipo en el centro: reconocido por el enlace (auto), el nombre de una marca, o ninguno.

Respuesta

200 OK
{
  "image": "data:image/png;base64,iVBORw0KGgo…",
  "format": "png",
  "remaining": 902,
  "limit": 1000,
  "resetsAt": "2026-12-01T00:00:00.000Z"
}

Los mismos números vienen en las cabeceras X-QrSensei-Remaining, X-QrSensei-Limit y X-QrSensei-Reset.

Autenticación

Cada llamada lleva la clave de tu aplicación en la cabecera Authorization: Bearer qs_live_….

  • La clave se muestra una vez, al crearla. Solo guardamos una huella: si la pierdes, crea una nueva en tu perfil y la antigua deja de funcionar.
  • Llama desde tu servidor, nunca desde un navegador o una app: una clave en el código del front-end la puede leer cualquiera.
  • No se guarda nada de los códigos: ni el contenido ni las imágenes. Solo un recuento por mes.

Contenidos

Los mismos tipos que el editor, con las mismas reglas. Esta tabla se lee de las reglas que comprueban cada llamada: no puede quedarse desactualizada.

typeObligatoriosOpcionales
urlurl—
texttext—
phonephone—
emailemailsubject, body
smsphonemessage
wifissid, passwordencryption, hidden
vcardfirstNamelastName, organization, title, phone, email, website, address, note
rawpayload—
whatsappphonemessage
telegramusernameOrHandlemessage
signalrecipientmessage
viberrecipientmessage
mecardnameorganization, phone, email, website, address, note
geolatitude, longitudelabel
googleMaps—latitude, longitude, query
waze—latitude, longitude, query
eventtitle, start, endlocation, description, allDay
pixpixKey, merchantName, merchantCityamount, txid, description
epcbeneficiaryName, ibanbic, amount, reference, remittance
paypalpaypalHandleOrEmailamount, currency, note, paymentUrl
mbwayphoneamount, note
cryptoWalletaddresscurrency, amount, network, memo
deepLinkuri—
otpissuer, accountName, secretotpType, algorithm, digits, period, counter
authuri—
structuredTexttext—
paramUrlbaseUrlparams
customContentcontent—
enlacesurlcalendarLink · 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

Una Wi-Fi sin contraseña lleva encryption "nopass". Un campo omitido queda vacío; un campo obligatorio que falta se nombra en el detail del error.

Estilos

Diseñados en tu perfil, con el código en vivo al lado. Cada uno tiene un id y uno es tu predeterminado; o escribe el estilo en la propia llamada, como style.

El aspecto de la marca, con su logotipo sobre una placa
{}
Para factura: negro, sin fondo
{ "color": { "kind": "solid", "color": "#18181B" }, "background": { "kind": "transparent" }, "quietZone": 2 }
Tinta en degradado sobre papel crema
{ "dots": "dots", "finders": "drop", "color": { "kind": "gradient", "type": "linear", "angle": 45, "stops": [ "#0F172A", "#1E40AF" ] }, "background": { "kind": "solid", "color": "#FFF7ED" } }

Un estilo solo se acepta si se lee: formas que combinan, y tinta más oscura que el papel con un contraste de al menos 4,5:1. Un código transparente se comprueba contra blanco, el papel de una factura.

Marcas

"auto" reconoce la marca por el enlace (un enlace de Instagram lleva el logotipo de Instagram). Un nombre fija la marca; "none" deja el centro libre. La lista también viene de GET /v1/brands.

Contra el phishing: en un enlace, una marca fija solo se usa si el enlace es de esa marca. El logotipo de un banco nunca acaba en un enlace falso.

  • qrsensei
  • instagram
  • facebook
  • linkedin
  • x
  • tiktok
  • youtube
  • github
  • spotify
  • whatsapp
  • telegram
  • signal
  • viber
  • snapchat
  • pinterest
  • threads
  • discord
  • reddit
  • messenger
  • googleMaps
  • appleMaps
  • waze
  • paypal
  • revolut
  • wise
  • stripe

Límites

Por mes1000 códigos por cuenta, todas las aplicaciones juntas. Vuelve a empezar el día 1, a las 00:00 UTC.
Por minuto30 llamadas por aplicación. Un código por llamada: no hay generación masiva.
No cuentaLlamadas con error, GET /v1/usage y GET /v1/brands.

Errores

Siempre un objeto error con code, message y, cuando ayuda, detail: el code es para tu programa, el message para quien lo lea. Una llamada con error no se cuenta.

EstadocodeCuándo
401missing-keyNo hay clave en la cabecera Authorization.
401invalid-keyLa clave no existe o fue sustituida.
400invalid-jsonEl cuerpo no es JSON.
400invalid-requestUn campo fuera de la lista, o un valor fuera de rango; detail lo indica.
400invalid-contentFalta un campo obligatorio o es incorrecto; detail lo indica.
400unknown-brandEsa marca no está en GET /v1/brands.
422brand-mismatchUna marca fija en un enlace que no es suyo.
404unknown-styleEse id de estilo no es de tu cuenta.
403not-developerEl modo desarrollador está desactivado en la cuenta.
403suspendedLa cuenta no puede usar la API ahora.
413too-largeEl cuerpo supera los 16 KB.
429quota-exceededSe acabaron los códigos de este mes.
429rate-limitedDemasiadas llamadas este minuto; Retry-After dice cuánto esperar.
500render-failedNo se pudo dibujar el código. No cuenta.
503api-offLa API está apagada un rato. No cuenta.