Authentication and access
API access is available on Personal and above. Create a key in API in the console. Choose Read only or Read and write, set an expiry, and copy the key when it is shown: you cannot reveal it again.
Send the key in Authorization: Bearer. Keys act as their creator within that workspace, with that person’s current role, and use the same plan limits and monthly file budget as website uploads. A key made by a viewer can read but not write, and a key stops working if its creator is removed from the workspace. A key stops working while the workspace is on a plan without API access.
Keep keys on the server or in your automation’s secret store, never in a published website. Revoke a key from API when it is no longer needed.
export SUNROSE_KEY="YOUR_API_KEY"
curl https://sunrose.dev/api/projects \
-H "Authorization: Bearer $SUNROSE_KEY" Key permissions
Read-only keys can list and read projects, versions, review links, and feedback. Read-and-write keys can also publish, create, revoke and extend review links, change feedback status, restore a version, reactivate a preview, and archive or restore projects, subject to plan allowances.
Keys cannot create or list API keys, delete projects, manage domains or addresses, set preview passwords, change search indexing, manage billing, branding, or the team. Those operations require a signed-in browser session. An invalid bearer token returns 401 even if a browser session is present.
REST endpoints
All paths below are relative to https://sunrose.dev. Replace path parameters with IDs from earlier responses. Write requests with a JSON body need Content-Type: application/json.
- GET
/api/projects List workspace projects, with mode (review or show). Archived projects are left out; add ?archived=1 to include them.
- GET
/api/projects/:id Read a project, versions, addresses, review links, and comments.
- GET
/api/projects/:id/feedback Filter by status (open, in_progress, ready, resolved), visibility (client, internal), and limit (1–200; default 50).
- GET
/api/projects/:id/feedback/export Download live comments and team notes as CSV (Studio and Agency).
- PATCH
/api/comments/:id JSON: {"status":"resolved"} and/or {"fixedIn":2} (the later version that addresses the comment; null takes it back). Changes internal status and the team-only fixed mark, not reviewer text.
- POST
/api/comments/:id/reply JSON: {"body":"…"}. Answers a reviewer’s comment; they read it under their own comment next time they open their link. Nothing is emailed. Add "shared":false for an internal note.
- POST
/api/projects/:id/review-links JSON: {"audience":"client"}. Returns a review URL. See review-link options below.
- PATCH
/api/projects/:id/review-links/:sessionId JSON: {"feedbackDueAt":"2026-12-01T09:00:00Z"} (or null to clear), and/or {"allowDownload":true}. Setting deadlines requires Studio or Agency.
- POST
/api/review-sessions/:id/revoke Revoke a review link.
- POST
/api/review-sessions/:id/extend Turn an expired client link back on for another full period. Links that were turned off, and team links, are refused.
- POST
/api/projects/:id/current JSON: {"versionId":"VERSION_ID"}. Make a ready version current; requires the version-restoration feature.
- POST
/api/projects/:id/reactivate Reactivate an expired preview.
- POST
/api/projects/:id/archive Take a project off the air without deleting it. Versions, comments, and approvals are kept. It frees a project slot, but its files still count toward your storage.
- POST
/api/projects/:id/unarchive Bring an archived project back. Returns 429 quota_projects if your plan’s project limit is full.
- GET
/api/projects/:id/versions/:versionId/export Download a version as a ZIP.
Publish a static site
Publishing takes three steps: declare every file, upload each file at its declared byte size, then commit the upload session. File paths must be relative to the site root, such as index.html or css/site.css.
The example below uses curl, jq, and a local index.html. Copy sessionId from the first response into SESSION_ID before the second command. Add every asset to the files array and upload each one before committing. For a new version, replace name with projectId in the declaration.
jq -n --argjson size "$(wc -c < index.html | tr -d ' ')" \
'{name:"My preview",mode:"review",files:[{path:"index.html",size:$size}]}' \
| curl https://sunrose.dev/api/uploads \
-H "Authorization: Bearer $SUNROSE_KEY" \
-H "Content-Type: application/json" --data-binary @-
# Set this to sessionId from the response above.
SESSION_ID="YOUR_SESSION_ID"
curl -X PUT "https://sunrose.dev/api/uploads/$SESSION_ID/file?path=index.html" \
-H "Authorization: Bearer $SUNROSE_KEY" --data-binary @index.html
curl -X POST "https://sunrose.dev/api/uploads/$SESSION_ID/commit" \
-H "Authorization: Bearer $SUNROSE_KEY" Read the publish result
Use mode review for client feedback or show for a plain preview. A commit response includes projectId, versionId, ordinal, url, and held. If held is true, the upload is waiting for a safety check; do not treat it as an available preview.
Commit succeeds only after all declared files arrive. Every version needs its full set of files, including unchanged assets. Executables are refused, and workspace file and storage limits still apply.
Create a review link
POST a JSON body with audience set to client or team. Optional fields include versionId, approvalEnabled, expiresInDays, feedbackDueAt, and allowDownload (reviewers may download the originals of an images-and-PDFs version). Without versionId, the link reviews the current version.
For client links, expiresInDays sets an idle period from 1 to 90 days; the default is 30, and visits renew it. A team link works once and must be opened within 15 minutes. Additional review capabilities depend on the workspace plan.
Store or deliver the returned URL securely. Review links grant access to their reviewed version and bypass the preview password.
Handle errors
Errors return JSON with code and message. Use code for program logic and message for a readable explanation. A plan_limit response names the plan required for that feature.
401 invalid_api_keyMissing, invalid, revoked, or expired API key.
403 read_only_keyThis operation needs a read-and-write key.
403 session_requiredUse a signed-in browser session for this operation.
403 plan_limitThe workspace plan does not include this feature.
404The requested resource is unavailable in this workspace.
409The operation conflicts with the current resource state.
422The request failed validation; inspect code and message.