API & webhooks

Available on Studio, Agency and Enterprise plans. Create keys in Plan & workspace → API keys.

Authentication

Send your key as a bearer token. Each key only sees its own workspace. Read-only keys can't make changes.

curl https://reviseberry.com/api/public/v1/projects \
  -H "Authorization: Bearer rbk_xxxxxxxx_…"

Errors look like { "error": { "code": "not_found", "message": "…" } }. Limits: 120 requests per minute per key (HTTP 429 with Retry-After). Plan limits return 402.

Endpoints

Base URL: https://reviseberry.com/api/public/v1

GET/workspaceThe workspace this key belongs to, with its plan. (read)
GET/usageCurrent usage against plan limits. (read)
GET/projectsList projects (?limit, ?offset). (read)
POST/projectsCreate a website project. Body: { name, url }. (write)
GET/projects/{id}One project. (read)
GET/projects/{id}/assetsImages, PDFs and videos in a project. (read)
GET/projects/{id}/commentsComments and replies (?status, ?limit, ?offset). Internal comments are included — the key belongs to your team. (read)
POST/projects/{id}/commentsAdd a comment or reply. Body: { body, parent_id?, visibility? }. (write)
GET/projects/{id}/review-linksGuest review links (no tokens). (read)
POST/projects/{id}/review-linksCreate a guest link. Body: { label?, can_comment?, can_approve?, days? }. The URL is returned once. (write)
GET/projects/{id}/approvalsApproval decision history. (read)
PATCH/comments/{id}Update status, priority or assignee_id. (write)

Webhooks

Events: project.created, asset.uploaded, asset.version_uploaded, comment.created, comment.updated, comment.resolved, comment.reopened, reply.created, approval.requested, approval.granted, approval.changes_requested.

Each request is a JSON POST with { id, type, created_at, workspace_id, data }. Verify the ReviseBerry-Signature header: t=timestamp,v1=hex, where v1 = HMAC-SHA256(secret, t + "." + rawBody). Reject timestamps older than 5 minutes. Use id to ignore duplicates.

const [t, v1] = header.split(",").map((p) => p.split("=")[1]);
const expected = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) reject();

Failed deliveries retry with backoff for about a day; an endpoint that keeps failing is switched off and shown in your settings. For Zapier or Make, paste a "Catch Hook" URL as a webhook destination.