# Claves de licencia

Una clave única por compra para tu software, con límite de dispositivos y validación desde tu app sin API key.

> [!WARNING]
> El SDK `vexor` de npm (Stripe, MercadoPago, PayPal, Square, Talo) está **deprecado**: ya no se mantiene y no debe usarse. vexorpay es hoy una **API REST de links de pago en USD, sin SDK oficial**. Migración: <https://developers.vexorpay.com/docs/migracion-desde-el-sdk>

Fuente: <https://developers.vexorpay.com/docs/api/license-keys>

Si vendes software, crea un [entregable](/docs/api/deliverables) de tipo
`license_key` y adjúntalo al link. Cada comprador recibe una clave única
(`MIAPP-7KQ2M-XW3PD-9H4TR-B2NCF-6YVJA`), que ve en la confirmación del pago y en su portal de compras. Tu app la valida
contra vexorpay **sin API key** (no pongas tu API key en una app que corre en la computadora del comprador).

- La clave sigue al acceso: deja de servir con el reembolso total, una disputa perdida, el fin de la suscripción o si le
  quitas el acceso (`POST /api/v1/orders/{id}/access`).
- `activation_limit`: en cuántos dispositivos se puede activar a la vez. El comprador libera un dispositivo desde su portal.
- `usage_limit`: cuántas veces se puede usar si tu app manda `increment_usage` (por ejemplo, créditos o exportaciones).
- `expires_after_days`: días de validez desde la compra, sólo en pagos únicos (en una suscripción dura lo que dure).

```bash
curl https://api.vexorpay.com/api/v1/deliverables \
  -X POST \
  -H "Authorization: Bearer vxp_live_tu_clave" \
  -H "Content-Type: application/json" \
  -d '{ "type": "license_key", "name": "Clave de Mi App", "license_prefix": "MIAPP", "activation_limit": 3 }'
```

## Desde tu app (público, sin API key)

Los tres endpoints reciben `key` (lo que ingresó el comprador) y `deliverable_id` (el id de tu entregable
`license_key`: una clave de otro producto no sirve). Nunca devuelven datos del comprador. Límite: 60 pedidos por minuto
por IP.

| Endpoint | Body | Qué hace |
| --- | --- | --- |
| `POST /api/v1/license-keys/activate` | `label` (nombre del dispositivo), `meta` opcional | Registra el dispositivo. Responde `201` con `activation.id`: guárdalo en el dispositivo. |
| `POST /api/v1/license-keys/validate` | `activation_id` opcional, `increment_usage` opcional | Responde `200` con `valid` y, si no sirve, `reason`. |
| `POST /api/v1/license-keys/deactivate` | `activation_id` | Libera el dispositivo. |

```bash
curl https://api.vexorpay.com/api/v1/license-keys/validate \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{ "key": "MIAPP-7KQ2M-XW3PD-9H4TR-B2NCF-6YVJA", "deliverable_id": "6a1f0c2e9b1d4e0012ab34cd", "activation_id": "6a2b…" }'
```

```json
{
  "valid": true,
  "reason": null,
  "status": "granted",
  "deliverableId": "6a1f0c2e9b1d4e0012ab34cd",
  "expiresAt": null,
  "usage": 0,
  "usageLimit": null,
  "activations": 1,
  "activationLimit": 3,
  "activation": { "id": "6a2b…", "label": "MacBook de Ana", "meta": null, "createdAt": "2026-11-05T12:00:00.000Z" }
}
```

`reason` es `disabled` (la desactivaste), `revoked` (el comprador perdió el acceso), `expired`, `usage_limit_reached` o
`activation_not_found` (ese dispositivo ya no está activado: pídele que active de nuevo).

## Gestionar las claves (con API key)

| Endpoint | Qué hace |
| --- | --- |
| `GET /api/v1/license-keys` | Tus claves, con la clave completa y sus activaciones. Filtros: `deliverable_id`, `customer_email`, `order_id`. |
| `GET /api/v1/license-keys/{id}` | Una clave. |
| `PATCH /api/v1/license-keys/{id}` | `status: disabled` la deja de aceptar; `granted` la reactiva. |
| `POST /api/v1/license-keys/{id}/rotate` | Clave nueva para la misma licencia (se filtró o se compartió): la anterior deja de servir al instante. |

Cada venta trae en `access.licenseKeyIds` las claves de esa compra ([Ventas](/docs/api/orders)).

## Errores

| Código | HTTP | Cuándo |
| --- | --- | --- |
| `validation_error` | 400 | Falta `key`, `deliverable_id`, `label` o `activation_id`. |
| `license_key_not_found` | 404 | La clave no existe para ese `deliverable_id`. |
| `license_key_not_usable` | 403 | Activar una clave desactivada, revocada o vencida (o reactivar una revocada). |
| `activation_limit_reached` | 403 | La clave ya está activada en `activation_limit` dispositivos. |
| `activation_not_found` | 404 | Liberar un dispositivo que no está activado con esa clave. |
| `rate_limited` | 429 | Más de 60 pedidos por minuto desde la misma IP. |
