Reports — compartir y embeber
Los reports con marca (la funcionalidad de cara al comerciante está documentada en Reports con marca) se pueden compartir una vez generados:
- Como URL pública en el host de la API de Clione (con token, sin login, cualquiera con el enlace).
- Como URL pública en tu propio dominio, cuando tu organización tiene un dominio de reports verificado.
- Dentro del dashboard, tras el login, limitado a tu organización.
Esta página documenta los endpoints y las cabeceras con las que se sirven los reports. Los reports se crean en la UI del dashboard (por debajo, POST /api/v1/dashboard/org/reports).
Resumen de endpoints
| Método | Ruta | Auth | Para qué |
|---|---|---|---|
POST | /api/v1/dashboard/org/reports/:id/share | JWT (owner / admin) | Genera o rota un token de compartición. |
DELETE | /api/v1/dashboard/org/reports/:id/share | JWT (owner / admin) | Revoca el token de compartición. |
GET | /api/v1/dashboard/org/reports/:id | JWT | Lee los metadatos del report (sin HTML). |
GET | /api/v1/dashboard/org/reports/:id/html | JWT | Lee el HTML renderizado para la vista previa en el dashboard. |
GET | /api/v1/public/reports/:shareToken | ninguna | Lee el HTML renderizado por token de compartición. |
GET | https://<your report domain>/r/:shareToken | ninguna | El mismo HTML, en tu dominio de reports verificado. |
1. Generar un token de compartición
POST /api/v1/dashboard/org/reports/:id/share
Authorization: Bearer <JWT>
Content-Type: application/json
{ "expiresInDays": 30 }
Cuerpo:
| Campo | Tipo | Notas |
|---|---|---|
expiresInDays | number o null | Días hasta que el token deja de funcionar. null, 0 u omitido = sin caducidad. |
Respuesta:
{
"id": "...",
"shareToken": "9f2c...64hex...",
"expiresAt": "2026-07-05T00:00:00.000Z"
}
Forma del token: 32 bytes aleatorios en hexadecimal (256 bits de entropía). Trátalo como un secreto bearer.
Volver a llamar a este endpoint rota el token: el anterior deja de funcionar al momento, aunque no hubiera caducado.
Revocar
DELETE /api/v1/dashboard/org/reports/:id/share
Authorization: Bearer <JWT>
Respuesta: 204 No Content. El token y su caducidad se borran; la URL anterior devuelve 404 desde ese momento.
2. URLs públicas
En el host de la API de Clione:
https://api.clione.ai/api/v1/public/reports/<shareToken>
Tu propio dominio de reports
Una organización con reports con marca puede servir sus enlaces de compartición desde un subdominio de su propio dominio, como reports.acme.com:
https://reports.acme.com/r/<shareToken>
El dominio se gestiona con:
| Método | Ruta | Para qué |
|---|---|---|
GET | /api/v1/dashboard/org/report-domain | reportDomain, reportDomainVerified, reportDomainCheckedAt y expectedTarget actuales |
PATCH | /api/v1/dashboard/org/report-domain | Fija o borra el hostname: { "reportDomain": "reports.acme.com" } |
POST | /api/v1/dashboard/org/report-domain/verify | Lanza la comprobación de DNS ahora |
Apunta el hostname al host de la API de Clione con un CNAME; expectedTarget en la respuesta es el destino exacto. La verificación acepta el CNAME o un hostname que resuelva a las mismas IPs, así que el CNAME flattening funciona. Una vez verificado, Clione emite su certificado TLS.
Un dominio de reports sirve /r/<shareToken>, para GET y HEAD, y nada más: cualquier otra ruta da 404. Solo sirve los reports de tu propia organización; el token de otra organización devuelve 404 ahí.
Configuración desde el lado del comerciante: Reports con marca — Dominio personalizado.
3. Fetch público
GET /api/v1/public/reports/:shareToken
Sin auth. El token es la credencial.
Respuestas
| Código | Cuándo |
|---|---|
200 OK | Token válido y sin caducar. El cuerpo es el HTML renderizado completo. |
404 Not Found | Token mal formado, desconocido, revocado o pasado su expiresAt. Siempre 404 (nunca 410 ni 403), para que la respuesta no revele si un token existió alguna vez. |
500 | Error del servidor. |
Cabeceras de respuesta
Content-Type: text/html; charset=utf-8
Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; img-src 'self' https: data:; script-src 'none'; frame-ancestors ...
Cross-Origin-Resource-Policy: cross-origin
Cross-Origin-Embedder-Policy: unsafe-none
Referrer-Policy: no-referrer
Cache-Control: private, max-age=300
script-src 'none': el report nunca ejecuta JavaScript.style-src 'unsafe-inline': el renderer mete todo el CSS inline.frame-ancestors: solo el propio origen del report y el dashboard de Clione, incluidos sus hosts de preview y de desarrollo local, pueden enmarcarlo. Mira Embeber.Referrer-Policy: no-referrer: los enlaces del report no filtran el token.- Caché: 5 minutos, privada. La rotación y la revocación se aplican en el servidor al momento.
4. Fetch con auth (vista previa en el dashboard)
GET /api/v1/dashboard/org/reports/:id/html
Authorization: Bearer <JWT>
El mismo cuerpo y las mismas cabeceras Content-Security-Policy, Cross-Origin-Resource-Policy y Cross-Origin-Embedder-Policy que el endpoint público, limitado a tu organización. No envía Referrer-Policy y no se cachea. Úsalo para previsualizar un report sin generar un token público.
5. Embeber
Un report compartido no se puede meter en un iframe de otro sitio: su frame-ancestors solo permite su propio origen y el dashboard de Clione (incluidos sus hosts de preview y de desarrollo local), y el navegador se niega a pintarlo dentro de cualquier otra página. Para poner un report en tu web:
- Enlázalo: la URL pública, o el
/r/<shareToken>de tu dominio de reports. - Sírvelo desde tu propio origen: trae el HTML de
/api/v1/public/reports/<shareToken>desde tu backend y devuélvelo desde tu dominio con tus propias cabeceras. El HTML es autocontenido (CSS inline, sin scripts).
Modelo de seguridad
- Los tokens tienen 256 bits de entropía de un CSPRNG. La fuerza bruta no es viable.
- Los tokens no están ligados a quien mira: cualquiera con la URL puede verlo.
- Revoca con
DELETE /share, o rota conPOST /share. - Los tokens pasado su
expiresAtdevuelven404; el report en sí no se borra. - Los reports no contienen scripts, y
script-src 'none'lo garantiza.
Relacionado
- Reports con marca: el how-to de cara al comerciante.
- Autenticación de la API: para el
Authorization: Bearer <JWT>de los endpoints del dashboard.