No code
Greenlight links
Signed, login-free links that answer one pitch from Raylight's email, or from anywhere your webhook posts them.
A greenlight link is bound to one production and one pitch version. Whoever holds it can read that pitch and answer it (greenlight, send comments, decline) without a Raylight account, until the pitch changes or the link expires. Nobody has to touch the API.
Where they appear
- Pitch ready emails. Every workspace owner and editor with production emails on gets Greenlight, Send comments and Decline links. Answers are recorded as
link:<email>. - Webhook payloads.
data.links.greenlight,data.links.commentanddata.links.declineon every event while the pitch is waiting for an answer. Raylight does not post them anywhere else, but your receiver can: a Slack message, a CI summary or a ticket comment. Answers are recorded aswebhook:<endpointId>, so you can tell which relay a greenlight came through.
Links are minted per recipient: each email and each endpoint's payload gets its own token for the same pitch.
Lifetime
A link lives 30 days or until the pitch moves on, whichever comes first. Reading a link returns its state:
| State | Meaning |
|---|---|
open | The link's pitch is current and waiting for an answer. Actions work. |
stale | The pitch moved on: a newer version exists, or the production was greenlit, declined or cancelled. The page still shows what it points at, and where to look instead. |
expired | Past the 30 days. The page still shows the pitch; actions refuse. |
So a Greenlight in an old email can never greenlight a version its reader did not see: once comments produce version 2, every version 1 link is stale.
A link also stops working when the person or endpoint it was minted for no longer stands behind it: the email's owner left the workspace or became a viewer, or the webhook endpoint was deleted. Those links answer 403 with code: "revoked", for reading as well as acting, since the summary is workspace data. Pausing an endpoint does not revoke links it already delivered.
The public page
Links open https://www.raylight.app/go/<token>, optionally with ?action=greenlight, comment or decline to lead with that button. The page shows the workspace name, intent, origin label, format, the pitch with its price, and how many rounds of comments are left. After the production wraps it shows the share and edit links instead. It never acts on load, since mail scanners prefetch every link; each action is an explicit button press that sends a POST.
A link shows only part of the production: the pitch and price, the format, the origin label, and the share links once it wraps. Never the brief's context, media URLs or code.
The public endpoints
The page is a thin client over four unauthenticated routes on https://api.raylight.app. The token is the whole credential; on top of the HMAC, the routes are rate limited to 30 requests a minute per IP.
| Call | Does | Answers |
|---|---|---|
GET /production-links/{token} | Read the link: state, pitch, price, format, origin, delivery, revisionsLeft, expiresAt. | 200 in every state, 403 revoked, 404 for a bad token |
POST /production-links/{token}/greenlight | Greenlight. Charges the credits and queues the video. | 200, 402 no credits, 403 revoked, 409 stale, 410 expired, 429 cap |
POST /production-links/{token}/comments | Send comments. Body { "comment": "..." }, up to 4,000 characters. | 200, 403 revoked, 409 stale, 410 expired, 429 out of rounds or monthly cap |
POST /production-links/{token}/decline | Decline. Body { "reason": "..." }, optional. | 200, 403 revoked, 409 stale, 410 expired |
Any of them answers 503 with code: "disabled" when links are switched off on the server. Every success carries { link } with the summary after the action, so your own buttons can call these directly and show the result. revisionsLeft counts the rounds of comments still allowed: a production gets 6 pitch versions, so 5 rounds after the first. The SDK wraps them as raylight.links.read, greenlight, comment and decline.
How they are made
A token is a small signed claim set (production id, pitch version, actor label, expiry), HMAC-signed with a server secret. Nothing is stored per link. Rotating that secret kills every link ever sent; that is the emergency brake.