---
title: "Códigos QR para desarrolladores: API REST, SDK y CLI — qr3.app Blog"
description: "Cómo generar códigos QR mediante programación, integrarlos en tu aplicación y reaccionar a los escaneos con webhooks: una guía técnica en profundidad."
canonical: "https://qr3.app/es/blog/qr-codes-for-developers/"
lang: "es"
robots: "index,follow,max-image-preview:large,max-snippet:-1"
---

# Códigos QR para desarrolladores: API REST, SDK y CLI — qr3.app Blog

> Cómo generar códigos QR mediante programación, integrarlos en tu aplicación y reaccionar a los escaneos con webhooks: una guía técnica en profundidad.

Canonical: <https://qr3.app/es/blog/qr-codes-for-developers/>

[← Blog](/es/blog/) [Tutoriales](/es/blog/category/tutorials/)

8 de marzo de 2026 8 min de lectura [Tutoriales](/es/blog/category/tutorials/) [API](/es/blog/tag/API/)[SDK](/es/blog/tag/SDK/)[Developer](/es/blog/tag/Developer/)[Webhooks](/es/blog/tag/Webhooks/)

# Códigos QR para desarrolladores: API REST, SDK y CLI

Cómo generar códigos QR mediante programación, integrarlos en tu aplicación y reaccionar a los escaneos con webhooks: una guía técnica en profundidad.

por **qr3.app Team**

![Códigos QR para desarrolladores: API REST, SDK y CLI](https://qr3-blog-agent.meistern.workers.dev/cdn/blog/qr-codes-for-developers/hero.png)

Como desarrollador, no quieres crear códigos QR de forma manual a través de un panel de control: quieres generarlos automáticamente, integrarlos en tu pipeline de build y reaccionar a los escaneos mediante webhooks. Para eso, exactamente, está hecho qr3.app.

## El stack

qr3.app es totalmente nativo de Cloudflare:

- **API Worker**: Hono sobre Cloudflare Workers (runtime de V8, sin dependencias de Node.js)

- **Redirect Worker**: un worker ultraligero, con redirecciones cacheadas en KV en menos de 5 ms p50

- **Base de datos**: Cloudflare D1 (SQLite) con multi-tenancy mediante `workspace_id`

- **Cola**: eventos de escaneo desacoplados a través de Cloudflare Queues

## Autenticación

Todas las peticiones a la API requieren un token Bearer y un ID de workspace:

```
POST https://qr3.app/v1/codes
Authorization: Bearer qr3_sk_...
Content-Type: application/json
```

Crea tus claves de API en [app.qr3.app/dashboard/api-keys](https://app.qr3.app/dashboard/api-keys).

## SDK de TypeScript

```
npm install @qr3/sdk
# o
pnpm add @qr3/sdk
```

```
import { QR3 } from "@qr3/sdk";

const client = new QR3({
  apiKey: process.env.QR3_API_KEY!,
  workspaceId: process.env.QR3_WORKSPACE_ID!,
});

// Create a QR code
const { data: code } = await client.codes.create({
  type: "url",
  url: "https://my-shop.com/product/42",
  title: "Product 42",
  tags: ["shop", "product"],
});

console.log(code.short_code);       // "r7f3Kx"
console.log(code.image_svg_url);    // SVG image URL
console.log(code.redirect_url);     // https://qr3.app/r7f3Kx

// Change URL later (dynamic codes only)
await client.codes.update(code.id, {
  url: "https://my-shop.com/product/42-new",
});

// Query analytics
const stats = await client.codes.stats(code.id, {
  from: "2026-01-01",
  to: "2026-03-31",
});
console.log(stats.data.total_scans); // e.g. 1247
```

## API REST directa

¿No quieres depender del SDK? La API REST se puede usar directamente:

```
# Create a QR code
curl -X POST https://qr3.app/v1/codes \
  -H "Authorization: Bearer $QR3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "url",
    "url": "https://my-site.com",
    "title": "My Site",
    "is_dynamic": true
  }'

# List all QR codes
curl https://qr3.app/v1/codes?limit=20 \
  -H "Authorization: Bearer $QR3_API_KEY"

# Upload a logo — embedded automatically in SVG and PNG from here on
curl -X POST https://qr3.app/v1/codes/qr_abc123/logo \
  -H "Authorization: Bearer $QR3_API_KEY" \
  -F "file=@logo.png"

# Download QR code as SVG (now includes the logo)
curl "https://qr3.app/v1/codes/r7f3Kx/qr.svg?size=8" \
  -o qrcode.svg
```

## CLI

Para scripting y CI/CD existe el `@qr3/cli`:

```
npm install -g @qr3/cli
qr3 login

# Create QR code and save as SVG
qr3 codes create --url "https://my-site.com" --title "CI Deploy" --output qr.svg

# Batch creation from CSV
qr3 codes batch import urls.csv --format svg --output ./qr-codes/
```

## Webhooks: reacciona a los escaneos

Los webhooks son la funcionalidad más potente: te permiten reaccionar en tiempo real a cada escaneo.

```
// Register a webhook
const { data: webhook } = await client.webhooks.create({
  url: "https://your-app.com/webhooks/qr3",
  events: ["qr.scanned", "qr.updated"],
});
```

### Payload del webhook

```
{
  "id": "evt_4f0c2a91d7e84b3c9a1f",
  "type": "qr.scanned",
  "created": "2026-03-15T14:30:00.000Z",
  "data": {
    "code_id": "qr_abc123",
    "short_code": "r7f3Kx",
    "scanned_at": "2026-03-15T14:30:00.000Z",
    "country": "DE",
    "device_type": "mobile",
    "os": "iOS",
    "browser": "Safari",
    "language": "de",
    "ab_variant": null,
    "redirected_to": "https://example.com/landing"
  }
}
```

### Verifica los webhooks (HMAC)

```
import { createHmac, timingSafeEqual } from "crypto";

export async function verifyWebhook(
  payload: string,
  signature: string,
  secret: string,
): Promise<boolean> {
  const expected = createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  const expectedBytes = Buffer.from(`sha256=${expected}`);
  const receivedBytes = Buffer.from(signature);
  return (
    expectedBytes.length === receivedBytes.length &&
    timingSafeEqual(expectedBytes, receivedBytes)
  );
}
```

## Límites de tasa (rate limiting)

Cada clave API puede enviar 60 peticiones por minuto, en todos los planes. La creación de códigos también tiene un límite diario por espacio de trabajo, el mismo en todos los planes: `POST /v1/codes` acepta nuevos códigos hasta que se hayan creado 200 ese día, y `POST /v1/codes/batch` hasta 10.000.

Cada respuesta autenticada incluye `X-RateLimit-Limit`. Una respuesta `429` también indica cuándo volver a intentarlo:

```
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1710510060
Retry-After: 60
```

## Formato de errores (RFC 7807)

Todos los errores siguen [RFC 7807 Problem Details](https://www.rfc-editor.org/rfc/rfc7807):

```
{
  "type": "https://docs.qr3.app/errors/validation",
  "title": "Validation Error",
  "status": 422,
  "detail": "url is required for type 'url'",
  "errors": [
    { "field": "url", "message": "Required" }
  ]
}
```

## Conclusión

qr3.app está diseñado desde cero como una herramienta para desarrolladores: API REST abierta, SDK con TypeScript de primera clase, CLI, webhooks y documentación OpenAPI completa. Echa un vistazo a la [documentación de la API](https://docs.qr3.app/en/api/) o empieza ya desde el [Dashboard](https://app.qr3.app/dashboard).

[← Todos los artículos](/es/blog/) [Empezar gratis](https://app.qr3.app/sign-up)
