Reports — share and embed
Branded reports — the merchant-facing feature is documented in Branded reports — can be shared once generated:
- As a public URL on the Clione API host (token-gated, no login, anyone with the link).
- As a public URL on your own domain, when your organization has a verified report domain.
- Inside the dashboard, behind login, scoped to your organization.
This page documents the endpoints and the headers reports are served with. Reports are created in the dashboard UI (POST /api/v1/dashboard/org/reports behind it).
Endpoint summary
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /api/v1/dashboard/org/reports/:id/share | JWT (owner / admin) | Mint or rotate a share token. |
DELETE | /api/v1/dashboard/org/reports/:id/share | JWT (owner / admin) | Revoke the share token. |
GET | /api/v1/dashboard/org/reports/:id | JWT | Read report metadata (no HTML). |
GET | /api/v1/dashboard/org/reports/:id/html | JWT | Read the rendered HTML for in-dashboard preview. |
GET | /api/v1/public/reports/:shareToken | none | Read the rendered HTML by share token. |
GET | https://<your report domain>/r/:shareToken | none | The same HTML, on your verified report domain. |
1. Mint a share token
POST /api/v1/dashboard/org/reports/:id/share
Authorization: Bearer <JWT>
Content-Type: application/json
{ "expiresInDays": 30 }
Body:
| Field | Type | Notes |
|---|---|---|
expiresInDays | number or null | Days until the token stops working. null, 0 or omitted = no expiry. |
Response:
{
"id": "...",
"shareToken": "9f2c...64hex...",
"expiresAt": "2026-07-05T00:00:00.000Z"
}
Token shape: 32 random bytes as hex (256 bits of entropy). Treat it as a bearer secret.
Calling this endpoint again rotates the token — the old one stops working immediately, even if it hadn't expired yet.
Revoke
DELETE /api/v1/dashboard/org/reports/:id/share
Authorization: Bearer <JWT>
Response: 204 No Content. The token and its expiry are cleared; the previous URL returns 404 from that moment on.
2. Public URLs
On the Clione API host:
https://api.clione.ai/api/v1/public/reports/<shareToken>
Your own report domain
An organization with branded reports can serve its share links from a subdomain of its own domain, such as reports.acme.com:
https://reports.acme.com/r/<shareToken>
The domain is managed with:
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/dashboard/org/report-domain | Current reportDomain, reportDomainVerified, reportDomainCheckedAt and expectedTarget |
PATCH | /api/v1/dashboard/org/report-domain | Set or clear the hostname: { "reportDomain": "reports.acme.com" } |
POST | /api/v1/dashboard/org/report-domain/verify | Run the DNS check now |
Point the hostname at the Clione API host with a CNAME — expectedTarget in the response is the exact target. Verification accepts either the CNAME or a hostname resolving to the same IPs, so CNAME flattening works. Once verified, Clione issues the TLS certificate for it.
A report domain serves /r/<shareToken>, for GET and HEAD, and nothing else: every other path is 404. It only serves your own organization's reports — another organization's token returns 404 there.
Setup from the merchant side: Branded reports — Custom domain.
3. Public fetch
GET /api/v1/public/reports/:shareToken
No auth. The token is the credential.
Responses
| Code | When |
|---|---|
200 OK | Token valid and not expired. Body is the full rendered HTML. |
404 Not Found | Token malformed, unknown, revoked or past expiresAt. Always 404 (never 410 or 403), so the response doesn't reveal whether a token ever existed. |
500 | Server error. |
Response headers
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'— the report never executes JavaScript.style-src 'unsafe-inline'— the renderer embeds all CSS inline.frame-ancestors— only the report's own origin and the Clione dashboard, including its preview and local-development hosts, may frame it. See Embedding.Referrer-Policy: no-referrer— links inside the report don't leak the token.- Cache: 5 minutes, private. Rotation and revocation apply on the server immediately.
4. Auth-gated fetch (dashboard preview)
GET /api/v1/dashboard/org/reports/:id/html
Authorization: Bearer <JWT>
Same body and the same Content-Security-Policy, Cross-Origin-Resource-Policy and Cross-Origin-Embedder-Policy headers as the public endpoint, scoped to your organization. It sends no Referrer-Policy and is not cached. Use it to preview a report without minting a public token.
5. Embedding
A shared report can't be iframed on another site: its frame-ancestors only allows its own origin and the Clione dashboard (including its preview and local-development hosts), and a browser refuses to render it inside any other page. To put a report on your site:
- Link to it — the public URL, or your report domain's
/r/<shareToken>. - Serve it from your own origin — fetch the HTML from
/api/v1/public/reports/<shareToken>in your backend and return it from your domain with your own headers. The HTML is self-contained (inline CSS, no scripts).
Security model
- Tokens are 256 bits of entropy from a CSPRNG. Brute force is not practical.
- Tokens are not tied to a viewer — anyone with the URL can view.
- Revoke with
DELETE /share, or rotate withPOST /share. - Tokens past
expiresAtreturn404; the report itself is not deleted. - Reports contain no scripts, and
script-src 'none'enforces it.
Related
- Branded reports — the merchant-facing how-to.
- API authentication — for the
Authorization: Bearer <JWT>on the dashboard endpoints.