# SDKs oficiales — ZoraLinks API v1

La API de ZoraLinks es **REST/JSON sobre HTTPS**. No es un servicio escrito en PHP, Node o Python: el mismo endpoint funciona desde cualquier lenguaje. Estos SDKs son clientes oficiales sin dependencias externas para que los equipos no tengan que escribir la capa HTTP.

- Base: `https://zoralinks.com/api/v1`
- Auth: `Authorization: Bearer zl_live_...` o `zl_test_...`
- Documentación: `docs/05-producto/api-publica-v1-2026-11-10.md`
- OpenAPI: [`openapi.yaml`](./openapi.yaml) (genera clientes para cualquier lenguaje)
- La clave debe vivir **solo en el servidor**; nunca en el navegador ni en repositorios.

## Node.js

Requiere Node 18+ (usa `fetch` global).

```js
import { ZoraLinks } from "./sdk/node/zoralinks.mjs";

const zora = new ZoraLinks({ apiKey: process.env.ZORALINKS_API_KEY });

const me = await zora.me();
const links = await zora.listLinks({ limit: 5 });
const stats = await zora.stats("all");
const analytics = await zora.analytics("30d");
```

## Python

Sin dependencias: usa la librería estándar.

```python
from sdk.python.zoralinks import ZoraLinks

zora = ZoraLinks()  # lee ZORALINKS_API_KEY
print(zora.me())
print(zora.list_links(limit=5))
print(zora.stats("all"))
print(zora.analytics("30d"))
```

## PHP

Requiere la extensión cURL.

```php
<?php
require __DIR__ . '/sdk/php/ZoraLinks.php';

$zora = new ZoraLinks(getenv('ZORALINKS_API_KEY'));
print_r($zora->me());
print_r($zora->listLinks(5));
print_r($zora->stats('all'));
print_r($zora->analytics('30d'));
```

## Respuestas

Los métodos devuelven el **JSON tal cual de la API**: por ejemplo, `me.data.user.email`, `listLinks().data` y `listLinks().pagination`. Así el SDK nunca oculta campos nuevos de la API.

## Métodos

| SDK | Métodos |
|---|---|
| Node | `me`, `listLinks`, `getLink`, `createLink`, `updateLink`, `deleteLink`, `stats`, `analytics`, `linkAnalytics` |
| Python | `me`, `list_links`, `get_link`, `create_link`, `update_link`, `delete_link`, `stats`, `analytics`, `link_analytics` |
| PHP | `me`, `listLinks`, `getLink`, `createLink`, `updateLink`, `deleteLink`, `stats`, `analytics`, `linkAnalytics` |

## Errores

Los tres SDKs lanzan una excepción con `status`, `error` y `message`:

- `401`: clave inválida o revocada.
- `403`: escritura con clave test o cuenta suspendida.
- `409`: alias en uso.
- `422`: datos inválidos.
- `429`: límite de 10 enlaces/hora o rate limit.
- `502`: la red no registró el enlace.

## PHP en Windows

Si cURL no encuentra el bundle de CA, define `ZORALINKS_CA_BUNDLE` con la ruta de un `cacert.pem`/`ca-bundle.crt`. El SDK no desactiva la verificación SSL.

## Prueba rápida

```bash
ZORALINKS_API_KEY=zl_test_... node -e "import('./sdk/node/zoralinks.mjs').then(async ({ZoraLinks})=>{const z=new ZoraLinks();console.log(await z.me())})"
ZORALINKS_API_KEY=zl_test_... python -c "import sys;sys.path.insert(0,'sdk/python');from zoralinks import ZoraLinks;print(ZoraLinks().me())"
ZORALINKS_API_KEY=zl_test_... php -r "require 'sdk/php/ZoraLinks.php'; print_r((new ZoraLinks())->me());"
```
