Authentication
Public read and widgets need no key. For write routes on paid plans, send Authorization: Bearer vr_live_….
| Prefix | Use | Where |
|---|---|---|
— | Public read and widgets. | Browser or server |
vr_live_ | Secret. Full write for your organisation. | Your servers |
vr_test_ | Secret, sandbox. Invitations are created but not emailed. | Development |
Public endpoints
No key required (60 requests/minute per IP). Responses are cached at the edge for 60 seconds.
| Endpoint | Returns |
|---|---|
GET /v1/businesses/{domain} | Profile, score, label, review count, breakdown, categories |
GET /v1/businesses/{domain}/reviews | Published reviews. ?stars=5|4|3|12&sort=recent|highest|lowest&limit=&cursor= |
GET /v1/businesses/{domain}/summary | Compact object used by widgets |
GET /v1/businesses/search?q= | Businesses and categories matching the query |
GET /v1/categories, /v1/categories/{slug}/businesses | Category list; ranked businesses in a category |
GET /v1/stats | Platform-wide totals |
curl https://api.vetted.reviews/v1/businesses/example.com/reviews?limit=2
{
"data": [
{ "id": 1042, "rating": 5, "title": "Switched in ten minutes",
"verification": "verified_invite", "verified_label": "Verified purchase",
"author": { "name": "Hannah W." }, "published_at": "2026-09-01T10:14:00Z", ... }
],
"next_cursor": "MjAyNi0wOS0wMSAxMDoxNDowMHwxMDQy"
}Business endpoints
Require a vr_live_ or vr_test_ key on a paid plan (600 requests/minute per key). Public read and widgets work without a key.
| Endpoint | Purpose |
|---|---|
GET /v1/me | Your organisation, plan and businesses |
POST /v1/invitations | Send one invitation: customer_email, optional reference_id and domain |
POST /v1/invitations/bulk | Up to 1,000 in one call |
GET /v1/invitations | List with status: sent, opened, completed |
POST /v1/reviews/{id}/reply | Create or update your public reply |
POST /v1/reviews/{id}/flag | Flag with reason and note |
GET /v1/analytics?range=30d|90d|365d | Score, volume, reply rate, unanswered |
GET/POST/DELETE /v1/webhooks | Manage signed event endpoints |
Pagination & errors
Lists take ?limit= (max 50) and ?cursor=, and return { data: [...], next_cursor: "…" | null }. Errors always have this shape:
HTTP 429 Too Many Requests
Retry-After: 23
{ "error": { "code": "rate_limited", "message": "Too many requests.", "doc_url": "…/docs#pagination" } }Codes: unauthorized 401 · forbidden 403 · not_found 404 · validation_failed 422 (with fields) · rate_limited 429 · plan_required 402.
Webhooks
Events: review.published, review.removed, reply.created, invitation.sent, invitation.opened, invitation.completed, score.updated.
Each delivery is a POST with header X-Vetted-Signature: t=…,v1=… where v1 = HMAC-SHA256(secret, t + "." + body). Reject if t is older than five minutes.
Widgets
Widgets do not need an API key. Paste the script once, then drop placeholder elements anywhere. Live API keys (vr_live_) are for server-side access on paid plans.
<script src="https://widgets.vetted.reviews/v1.js" async></script> <div class="vetted-widget" data-type="badge" data-theme="light" data-size="md"></div> <div class="vetted-widget" data-type="carousel" data-count="8" data-schema="true"></div> <div class="vetted-widget" data-type="product" data-sku="SKU-123"></div>
| Attribute | Values |
|---|---|
data-type | badge · micro · seal · carousel · product |
data-theme | light (default) · dark · auto |
data-size | sm · md · lg (badge) |
data-accent | Hex colour for the score and links, e.g. #0B6E5C |
data-bg | Hex background colour |
data-min-stars | 4 or 5 — carousel only shows those ratings |
data-min-score | Hide the widget unless the live score is at least this |
data-count | 4–12 (carousel) |
data-schema | true to emit AggregateRating JSON-LD |
data-domain | Business domain (required) |
Widgets render in a Shadow DOM, set no cookies, and are cached at the edge for five minutes. If a business has no reviews yet the widget renders a neutral "Be the first to review" state — never a fake score.
Email signatures (and anywhere a script cannot run) can use a static PNG that tracks the live score:
https://widgets.vetted.reviews/img/your-domain.com.png