Skip to content

Turn the run’s public report on (the link is shown once)

PUT
/v1/runs/{id}/public-report
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.

id
required
string
Media type application/json
object
expiresAt

ISO 8601 with an offset; 1 hour to 30 days from now. Default: 7 days from now.

string format: date-time
password

Printable ASCII only. Optional; never returned.

string
>= 8 characters <= 128 characters /^[\x20-\x7e]+$/
Example
{
"password": "correct horse battery staple"
}

A live link already exists: the state only, no token

Media type application/json
object
enabled
required
boolean
createdAt

When the link was made. Only when enabled.

string format: date-time
createdBy

The id of the person who made it. Only when enabled.

string
expiresAt

When the link stops answering (#1264). Only when enabled.

string format: date-time
expired

expiresAt has passed: the address answers 410, and PUT makes a new link. Only when enabled.

boolean
lockedUntil

Set while too many wrong passwords have locked the address (10 in 15 minutes): until when. Null otherwise. Per API instance. Only when enabled.

string | null format: date-time
passwordProtected

A password is set (the server keeps only a salted hash of it). Only when enabled.

boolean
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

Media type application/json
object
enabled
required
boolean
createdAt

When the link was made. Only when enabled.

string format: date-time
createdBy

The id of the person who made it. Only when enabled.

string
expiresAt

When the link stops answering (#1264). Only when enabled.

string format: date-time
expired

expiresAt has passed: the address answers 410, and PUT makes a new link. Only when enabled.

boolean
lockedUntil

Set while too many wrong passwords have locked the address (10 in 15 minutes): until when. Null otherwise. Per API instance. Only when enabled.

string | null format: date-time
passwordProtected

A password is set (the server keeps only a salted hash of it). Only when enabled.

boolean
token

43 characters of base64url (256 bits). In THIS answer and nowhere else: the server keeps only a hash, and no route returns it again.

string
path

Where the report is on the dashboard: /public/report/<token>.

string
url

The whole link, when the server knows the dashboard’s address (WEB_BASE_URL); else null and the page builds it from path.

string | null
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

Media type application/json
object
error
required
string
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)

Media type application/json
object
error
required
string
Example generated
{
"error": "example"
}

No such run in your projects

Media type application/json
object
error
required
string
Example generated
{
"error": "example"
}

A live link already exists and the body asks for a date or a password: code: link_exists

Media type application/json
object
error
required
string
Example generated
{
"error": "example"
}

The body is over 4096 bytes

Media type application/json
object
error
required
string
Example generated
{
"error": "example"
}

Rate limit exceeded