Turn the run’s public report on (the link is shown once)
const url = 'https://beta-api.plune.ai/v1/runs/example/public-report';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"password":"correct horse battery staple"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://beta-api.plune.ai/v1/runs/example/public-report \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "password": "correct horse battery staple" }'Makes the public link of the run (#1263), GET /public/report/<token>, readable by anyone who holds it, with no account. The token is 256 random bits and is in the 201 answer ONCE: only its SHA-256 is stored, so nothing can show it again, and the owner must copy the link then. The body is optional: { expiresAt?, password? } (#1264). A link always ends: expiresAt (ISO 8601 with an offset) is at least an hour and at most 30 days from now, and when it is left out the link lives 7 days. password is optional, 8 to 128 printable ASCII characters; it is checked on the server, and only a salted scrypt hash of it is stored. A run that already has a LIVE link answers 200 with the state only (enabled, createdAt, createdBy, expiresAt, expired, passwordProtected, lockedUntil) and never the token; the link in hand keeps working. Sending a date or a password with it is refused, 409 link_exists, not dropped: revoke first. The body is at most 4096 bytes (413 past that). A link that has EXPIRED is replaced: 201 with a new token. To change a date or a password, or to get a new link early, revoke (DELETE) and make one again: the old address is dead from the revoke on. Written to the audit log as public_report create (update when it replaced an expired link) with the date and whether a password is set, without the token, the password or any hash. The project’s owner only: a member is refused with 403 project owner only, a reader with 403 read-only member.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Request Body
Section titled “Request Body ”object
ISO 8601 with an offset; 1 hour to 30 days from now. Default: 7 days from now.
Printable ASCII only. Optional; never returned.
Example
{ "password": "correct horse battery staple"}Responses
Section titled “ Responses ”A live link already exists: the state only, no token
object
When the link was made. Only when enabled.
The id of the person who made it. Only when enabled.
When the link stops answering (#1264). Only when enabled.
expiresAt has passed: the address answers 410, and PUT makes a new link. Only when enabled.
Set while too many wrong passwords have locked the address (10 in 15 minutes): until when. Null otherwise. Per API instance. Only when enabled.
A password is set (the server keeps only a salted hash of it). Only when enabled.
Example generated
{ "enabled": true, "createdAt": "2026-04-15T12:00:00Z", "createdBy": "example", "expiresAt": "2026-04-15T12:00:00Z", "expired": true, "lockedUntil": "2026-04-15T12:00:00Z", "passwordProtected": true}Turned on: the new link, with its token — this once
object
When the link was made. Only when enabled.
The id of the person who made it. Only when enabled.
When the link stops answering (#1264). Only when enabled.
expiresAt has passed: the address answers 410, and PUT makes a new link. Only when enabled.
Set while too many wrong passwords have locked the address (10 in 15 minutes): until when. Null otherwise. Per API instance. Only when enabled.
A password is set (the server keeps only a salted hash of it). Only when enabled.
43 characters of base64url (256 bits). In THIS answer and nowhere else: the server keeps only a hash, and no route returns it again.
Where the report is on the dashboard: /public/report/<token>.
The whole link, when the server knows the dashboard’s address (WEB_BASE_URL); else null and the page builds it from path.
Example generated
{ "enabled": true, "createdAt": "2026-04-15T12:00:00Z", "createdBy": "example", "expiresAt": "2026-04-15T12:00:00Z", "expired": true, "lockedUntil": "2026-04-15T12:00:00Z", "passwordProtected": true, "token": "example", "path": "example", "url": "example"}Invalid body: a date that is not ISO 8601 with an offset, less than an hour or more than 30 days away, a password outside 8-128 printable ASCII characters, or a field this route does not know
object
Example generated
{ "error": "example"}No / invalid token or session
A reader (read-only member), or a member who is not an owner (project owner only)
object
Example generated
{ "error": "example"}No such run in your projects
object
Example generated
{ "error": "example"}A live link already exists and the body asks for a date or a password: code: link_exists
object
Example generated
{ "error": "example"}The body is over 4096 bytes
object
Example generated
{ "error": "example"}Rate limit exceeded