---
title: "Exchange a render token for an ephemeral render session."
method: POST
path: "/auth/render"
tags: ["auth"]
---

# Exchange a render token for an ephemeral render session.

`POST /auth/render`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/auth/render`
- Auth: none required

The headless render flow's credential exchange (ADR-0024). The dvt-render service loads
the SPA with a **single-use, 60-second** `dvt_render_…` token; before mounting anything
the SPA posts it here. A successful exchange consumes the token atomically (it can never
be exchanged twice) and sets the sealed `dvt_render_session` cookie (HttpOnly, 120s),
whose actor is **forced to the viewer role**, typed `render`, and confined to metadata
reads of the one scoped dashboard, `/v1/me`, and `POST /v1/data/query` — regardless of
the requesting user's real role. Note the data bound honestly: `data/query` is
org-wide (free-form SQL against any org source, like any org viewer), so the session's
data access is org-scoped for its ≤120s lifetime even though its dashboard reads are
not (ADR-0024 §2). Unknown, already-used, and expired tokens are indistinguishable.

## Request body

- object
  - `token` string, required: The single-use render token (`dvt_render_…`) from the render URL.

## Response `200`

Token consumed; render-session cookie set. Returns the session's scope.

- object
  - `data` object
    - `orgId` string, uuid
    - `dashboardId` string, uuid

## Other responses

- `403`: Problem type `render-token-invalid` — the token is unknown, already used, or expired (deliberately indistinguishable).

---

[API](https://skmtc.dev/dvt/apis/dvt-rest-api.md) · [All operations](https://skmtc.dev/dvt/apis/dvt-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dvt/apis/dvt-rest-api/revisions/00016f504165?raw)
