Saltar al contenido principal

Reports — compartir y embeber

Los reports con marca — la funcionalidad de cara al comerciante está documentada en Reports con marca — pueden compartirse de tres maneras una vez generados:

  1. Como URL pública (con token, sin auth, cualquiera con el enlace).
  2. Como URL del dashboard (con auth, solo tu tenant).
  3. Embebidos como iframe en tu propio sitio (usando cualquiera de las dos anteriores).

Esta página documenta los endpoints y el contrato de iframe. Para crear reports programáticamente, mira la API del dashboard (POST /api/v1/dashboard/org/reports) — pero en la práctica los reports se crean en la UI del dashboard y se comparten vía los endpoints de abajo.


Resumen de endpoints

MétodoPathAuthPropósito
POST/api/v1/dashboard/org/reports/:id/shareJWT (owner / admin)Acuñar o rotar un share token.
DELETE/api/v1/dashboard/org/reports/:id/shareJWT (owner / admin)Revocar el share token.
GET/api/v1/dashboard/org/reports/:idJWTLeer metadatos del report (sin HTML).
GET/api/v1/dashboard/org/reports/:id/htmlJWTLeer el HTML renderizado para preview en dashboard.
GET/api/v1/public/reports/:shareTokenningunaLeer el HTML renderizado por share token.

URL base de producción: https://api.clione.ai.


1. Acuñar una URL de share

POST /api/v1/dashboard/org/reports/:id/share
Authorization: Bearer <JWT>
Content-Type: application/json

{ "expiresInDays": 30 }

Body:

CampoTipoNotas
expiresInDaysnumber o nullDías hasta que el token deja de funcionar. null u omitido = sin expiración.

Respuesta:

{
"id": "rep_...",
"shareToken": "9f2c...64hex...",
"expiresAt": "2026-07-05T00:00:00.000Z"
}

Forma del token: 32 bytes de hex aleatorio (256 bits de entropía). Trátalo como bearer secret.

El token está unique-indexed en la BBDD. Re-llamar a este endpoint rota el token — el viejo deja de funcionar de inmediato, aunque no hubiera expirado todavía.

Revocar

DELETE /api/v1/dashboard/org/reports/:id/share
Authorization: Bearer <JWT>

Respuesta: 204 No Content. Pone shareToken=null y expiresAt=null. La URL anterior devuelve 404 desde ese momento.


2. Construir la URL pública

Dominio por defecto:

https://app.clione.ai/r/<shareToken>

La ruta /r/:token del dashboard es un wrapper fino que iframea https://api.clione.ai/api/v1/public/reports/:shareToken. Puedes enlazar a cualquiera:

  • https://app.clione.ai/r/<token> — lo que ven los usuarios finales, incluye el chrome de la app.
  • https://api.clione.ai/api/v1/public/reports/<token> — HTML crudo, lo que embebes.

Dominio personalizado (Pro y Agency)

Si el tenant tiene un dominio personalizado verificado (reports.acme.com), las URLs compartidas lo usan en su lugar:

https://reports.acme.com/r/<shareToken>

El setup está documentado en Reports con marca — Dominio personalizado. El dominio personalizado es un CNAME a custom-reports.clione.ai y es verificado por el dashboard contra tanto el CNAME como la IP que resuelve (tolerante a CNAME-flattening).


3. Endpoint público de fetch

GET /api/v1/public/reports/:shareToken

Sin auth. El token valida la petición.

Respuestas

CódigoCuándo
200 OKToken válido y no expirado. El body es el HTML renderizado completo.
404 Not FoundToken desconocido, revocado o pasado el expiresAt. Devolvemos 404 (no 410) intencionalmente — no leakeamos si un token existió alguna vez.
500Error del servidor.

Headers 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 'self' https://app.clione.ai https://*.vercel.app http://localhost:5173
Cross-Origin-Resource-Policy: cross-origin
Cross-Origin-Embedder-Policy: unsafe-none
Referrer-Policy: no-referrer
Cache-Control: private, max-age=300

Notas sobre el CSP:

  • script-src 'none' — el HTML renderizado nunca ejecuta JS. Puedes embeberlo con seguridad en cualquier sitio.
  • style-src 'unsafe-inline' es necesario porque el renderer embebe todo el CSS inline.
  • frame-ancestors permite el dashboard de Clione, deployments preview de Vercel y localhost. Para embeber en tu propio sitio, necesitarás usar la URL renderizada por dashboard (que tiene el mismo body pero sin la restricción de frame-ancestors relativa a tu dominio) o contactarnos para añadir tu dominio a la allowlist.

Caché: 5 minutos privado. La rotación del token invalida de inmediato en el lado servidor, así que un fetch fresco tras revoke siempre da 404.


4. Fetch con auth (preview de dashboard)

GET /api/v1/dashboard/org/reports/:id/html
Authorization: Bearer <JWT>

Mismo body que el endpoint público, mismos headers, pero con alcance al tenant del solicitante. Los superadmins también ven reports cross-tenant (los que tienen tenantId=null creados vía /admin/reports/from-scans).

Úsalo cuando quieres preview dentro de una herramienta con alcance de tenant y no quieres acuñar un token público.


5. Patrón de embed iframe

Los reports están diseñados para ser iframeados. El CSP lo permite para app.clione.ai de fábrica.

<iframe
src="https://app.clione.ai/r/9f2c...64hex..."
title="Q2 SEO performance — Acme"
style="width:100%; height:100vh; border:0;"
loading="lazy"
referrerpolicy="no-referrer"
></iframe>

Para un embed de dominio personalizado:

<iframe
src="https://reports.acme.com/r/9f2c...64hex..."
...
></iframe>

Si necesitas embeber en un dominio que no está en la lista de frame-ancestors, dos opciones:

  • Recomendado — pide que añadan tu dominio. Email a admin@takefortytwo.com con el hostname.
  • Workaround — proxea el HTML del report a través de tu backend y vuelve a servirlo desde tu propio origin con tu propio CSP.

Modelo de seguridad

  • Los tokens son 256 bits de entropía de un CSPRNG. Brute force no es práctico.
  • Los tokens no tienen alcance a una identidad de viewer — cualquiera con la URL puede ver.
  • La rotación de token es la única primitiva de revocación (configura shareToken=null o llama a POST /share para acuñar uno nuevo).
  • Los tokens con expiresAt en el pasado devuelven 404 en lookup — la fila no se borra.
  • El HTML se sanitiza en tiempo de render — no hay script tags en la salida independientemente de los datos de origen.
  • El endpoint configura Referrer-Policy: no-referrer para que el navegador que ve no leakee el token a enlaces salientes dentro del report.

Relacionados