SSR API (IN BETA)
The Feefo Server-Side Rendering (SSR) API allows you to inject Feefo review structured data directly into the HTML generated by your server using Schema.org JSON-LD.
This structured data can represent:
- Product ratings and product reviews
- Service ratings and service reviews
- Merchant organisation information
- AI-generated product review summaries and review topics (where enabled)
Available Resources
| Endpoint | Schema.org Type | Purpose |
|---|---|---|
GET /widgets-review-service/ssr/product | Product | Product ratings, reviews, and AI summaries |
GET /widgets-review-service/ssr/service | Organization | Merchant info, service ratings, and service reviews |
The returned JSON payload should be injected into your server-rendered HTML inside a <script type="application/ld+json"> tag.
Before You Start
To integrate with the SSR API, ensure you have:
- A Feefo App Key with the SSR API option enabled.
- An OAuth 2.0 access token generated using your App Key credentials.
- Your Feefo merchant slug.
- The relevant widget type (e.g.,
on-pageorpop-up). - (For product requests) A product
sku,parent_sku, orSERIEStag.
Enable SSR API Access
App Keys are managed inside the Feefo Hub:
- Navigate to Settings → Connectivity → App Keys.
- Create a new App Key or edit an existing one.
- Enable the SSR API option.
Principle of Least PrivilegeWe recommend granting an App Key access only to the specific Feefo services required by your integration.
Authentication
Feefo APIs authenticate via OAuth 2.0. Use the Client ID and Client Secret associated with your App Key to generate a Bearer token.
Request Access Token
POST [https://api.feefo.com/api/oauth/v2/token](https://api.feefo.com/api/oauth/v2/token)
Content-Type: application/json{
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"grant_type": "client_credentials"
}Token Response
{
"access_token": "your-access-token",
"expires_in": 3600,
"token_type": "bearer"
}expires_inindicates the token lifetime in seconds. When the token expires, request a new one using the same credentials.- Pass the token in the
Authorizationheader of all SSR requests:
Authorization: Bearer your-access-token
Keep Credentials Server-SideNever expose your
client_secretoraccess_tokenin client-side browser JavaScript. OAuth token generation and SSR API calls must only happen in a trusted server environment.
Product Structured Data
Retrieve Schema.org Product structured data for an individual product, parent product, or product series.
GET /widgets-review-service/ssr/productQuery Parameters
| Parameter | Required | Description |
|---|---|---|
slug | Yes | Your Feefo merchant slug. |
widget | Yes | Widget type/configuration (e.g., on-page, pop-up). |
sku | Conditional | Individual product SKU. |
parent_sku | Conditional | Parent product SKU. |
schema_id | No | The exact @id URI of your existing on-page Product schema (URL-encoded). When provided, Feefo targets this ID to merge review ratings with your existing product schema. If omitted, a stable fallback @id is generated automatically. |
tags | No | Restricts ratings, reviews, and AI content to reviews carrying the specified tag (key:value). Repeat the parameter to supply multiple tags. |
Product Identifier RequirementYou must supply at least one of the following:
sku,parent_sku, or atagsparameter with the keySERIES(e.g.,tags=SERIES:my-series).
Example Requests
Standard SKU Request:
GET /widgets-review-service/ssr/product?slug=your-merchant&sku=ABC123&widget=on-page
Authorization: Bearer your-access-tokenParent SKU Request:
GET /widgets-review-service/ssr/product?slug=your-merchant&parent_sku=PARENT123&widget=on-page
Authorization: Bearer your-access-tokenSERIES Tag Request (instead of SKU):
GET /widgets-review-service/ssr/product?slug=your-merchant&widget=on-page&tags=SERIES:my-series
Authorization: Bearer your-access-tokenExample Product Response (200 OK)
200 OK)Up to five eligible reviews are included in the response. Exact fields depend on available product and review data.
{
"@context": "[https://schema.org](https://schema.org)",
"@type": "Product",
"@id": "[https://www.example.com/products/example-product#Product](https://www.example.com/products/example-product#Product)",
"name": "Example Product",
"description": "Example product description",
"aggregateRating": {
"@type": "AggregateRating",
"bestRating": 5,
"worstRating": 1,
"ratingValue": 4.7,
"reviewCount": 124
},
"review": [
{
"@type": "Review",
"author": {
"@type": "Person",
"name": "Trusted Customer"
},
"reviewRating": {
"@type": "Rating",
"bestRating": 5,
"worstRating": 1,
"ratingValue": 5
},
"reviewBody": "An example customer review.",
"datePublished": "2026-01-15T10:30:00Z",
"publisher": {
"@type": "Organization",
"@id": "[https://www.feefo.com/#organization](https://www.feefo.com/#organization)",
"name": "Feefo",
"url": "[https://www.feefo.com](https://www.feefo.com)"
},
"url": "[https://www.feefo.com/example-review](https://www.feefo.com/example-review)",
"@id": "[https://www.feefo.com/example-review#review](https://www.feefo.com/example-review#review)",
"inLanguage": "en-GB",
"itemReviewed": {
"@id": "[https://www.example.com/products/example-product#Product](https://www.example.com/products/example-product#Product)"
}
}
]
}AI Product Review Content
Depending on your Feefo configuration and widget type, the product response may include AI-generated review summaries (additionalProperty) and review topics (positiveNotes / negativeNotes):
{
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "Customer review summary",
"value": "Customers frequently praise the product's quality and ease of use."
},
{
"@type": "PropertyValue",
"name": "Review summary source",
"value": "Feefo verified customer reviews"
}
],
"positiveNotes": {
"@type": "ItemList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Quality"
},
{
"@type": "ListItem",
"position": 2,
"name": "Ease of use"
}
]
}
}(Negative topics follow the exact same ItemList structure under negativeNotes. These fields are omitted if AI features are disabled for the widget or insufficient data exists.)
Schema @id and Graph Linking
@id and Graph LinkingSearch engines use the Schema.org @id property as a primary key to connect separate JSON-LD blocks describing the same entity:
- If you already render
ProductJSON-LD on your page: Pass the exact@idfrom your existing<script type="application/ld+json">node into theschema_idquery parameter (URL-encoded). Search engines will merge Feefo’s ratings and reviews with your price, availability, and image metadata. - If you do not render existing
ProductJSON-LD: Omitschema_id. Feefo will generate a stable fallback@id.
Service Structured Data
Retrieve Schema.org Organization structured data representing your business and service reviews.
GET /widgets-review-service/ssr/serviceQuery Parameters
| Parameter | Required | Description |
|---|---|---|
slug | Yes | Your Feefo merchant slug. |
widget | Yes | Widget type/configuration (e.g., on-page, pop-up). |
tags | No | Restricts ratings and reviews to reviews carrying the specified tag (key:value). Repeat the parameter to supply multiple tags. |
Example Request
GET /widgets-review-service/ssr/service?slug=your-merchant&widget=on-page
Authorization: Bearer your-access-tokenExample Service Response (200 OK)
200 OK)Up to five eligible service reviews are included. Fields such as address, telephone, image, and url depend on the merchant details configured in your Feefo account.
{
"@context": "[https://schema.org](https://schema.org)",
"@type": "Organization",
"@id": "[https://www.feefo.com/en-GB/reviews/example-merchant](https://www.feefo.com/en-GB/reviews/example-merchant)",
"sameAs": "[https://www.feefo.com/en-GB/reviews/example-merchant](https://www.feefo.com/en-GB/reviews/example-merchant)",
"url": "[https://www.example.com](https://www.example.com)",
"image": "[https://api.feefo.com/api/merchant-image/example-logo.png](https://api.feefo.com/api/merchant-image/example-logo.png)",
"name": "Example Merchant",
"aggregateRating": {
"@type": "AggregateRating",
"bestRating": 5,
"worstRating": 1,
"ratingValue": 4.8,
"reviewCount": 1500
},
"review": [
{
"@type": "Review",
"author": {
"@type": "Person",
"name": "Trusted Customer"
},
"reviewRating": {
"@type": "Rating",
"bestRating": 5,
"worstRating": 1,
"ratingValue": 5
},
"reviewBody": "Excellent service.",
"datePublished": "2026-01-15T10:30:00Z",
"publisher": {
"@type": "Organization",
"@id": "[https://www.feefo.com/#organization](https://www.feefo.com/#organization)",
"name": "Feefo",
"url": "[https://www.feefo.com](https://www.feefo.com)"
}
}
],
"address": {
"@type": "PostalAddress",
"addressCountry": "GB",
"addressLocality": "London",
"addressRegion": "Greater London",
"postalCode": "AB1 2CD",
"streetAddress": "1 Example Street"
},
"telephone": "01234567890"
}Filtering by Tags & Widget Configuration
Filtering by Tags
The tags parameter works identically across both /product and /service endpoints:
- Format: Must use
key:valuesyntax (e.g.,tags=incentivised:1). Supplying a tag without a value (e.g.,tags=incentivised) returns400 Bad Request. - Multiple tags: Repeat the query parameter (
tags=incentivised:1&tags=colour:red). Order does not matter. - AND logic: When multiple tags are provided, a review must carry all specified tags to be included.
- Scope: Tag filtering applies to the
aggregateRating,reviewCount,reviewarray, and (for products) AI summaries and topics.
GET /widgets-review-service/ssr/product?slug=your-merchant&sku=ABC123&widget=on-page&tags=incentivised:1&tags=colour:redUnderstanding the widget Parameter
widget ParameterThe widget parameter (e.g., widget=on-page or widget=pop-up) tells Feefo which widget configuration and customisations to apply when generating structured data—including whether AI summaries or topics are enabled. Always pass the widget type matching the Feefo widget rendered on that page.
Response Statuses & Caching Behaviour
| Status Code | Meaning | Behaviour & Action Required |
|---|---|---|
200 OK | Structured data is ready. | Inject the JSON response body into your page HTML inside a <script type="application/ld+json"> tag. |
204 No Content | Data is currently being generated asynchronously. | Returns an empty body with Cache-Control: no-store. Do not cache 204 responses. Render the page without Feefo JSON-LD and retry on a subsequent request. |
400 Bad Request | Missing or invalid parameters. | Verify slug and widget are present, product requests include sku/parent_sku/SERIES, and all tags follow key:value format. |
Asynchronous First-Request Flow
Feefo generates SSR payloads asynchronously per unique combination of parameters (including distinct tag combinations). The first time a unique combination is requested, the API triggers generation and returns 204 No Content:
Your Server Feefo SSR API
| |
|--- GET /ssr/product (1st request) --->|
|<-- 204 No Content --------------------| (Triggers async generation)
| |
| ... (SSR payload generated) ... |
| |
|--- GET /ssr/product (later request) ->|
|<-- 200 OK (Schema.org JSON-LD) -------|
Handling 204 Responses
- Do not treat
204 No Contentas an application error.- Do not cache
204responses.- Do not retry in a tight synchronous loop during page load—either wait for a subsequent page render or use bounded background polling.
Automatic Data Refresh
Feefo stores generated SSR results and periodically refreshes them asynchronously without blocking live requests. Because SSR endpoints are not served from a CDN cache, you do not need to manage cache invalidation when new reviews arrive.
Adding the Response to Your Page
Serialise the 200 OK JSON response into a <script type="application/ld+json"> tag in your HTML <head> or <body>. Do not render the JSON as visible page text.
Required ScriptidPrefixTo allow Feefo's client-side widget to detect existing server-rendered schema and avoid duplicate injection, include an
idattribute on the<script>tag using the appropriate prefix (you may append any unique suffix):
- Product schema:
id="onpage-product-schema-<suffix>"- Service schema:
id="onpage-organization-schema-<suffix>"
Example HTML Implementation
<!doctype html>
<html lang="en">
<head>
<title>Example Product</title>
<script id="onpage-product-schema-ABC123" type="application/ld+json">
{
"@context": "[https://schema.org](https://schema.org)",
"@type": "Product",
"@id": "[https://www.example.com/products/example-product#Product](https://www.example.com/products/example-product#Product)",
"name": "Example Product",
"aggregateRating": {
"@type": "AggregateRating",
"bestRating": 5,
"worstRating": 1,
"ratingValue": 4.7,
"reviewCount": 124
}
}
</script>
</head>
<body>
<!-- Page content -->
</body>
</html>Recommended Server-Side Flow
- Receive an incoming page request on your server.
- Call
GET /widgets-review-service/ssr/product(or/service) withAuthorization: Bearer <access-token>, matching your on-pagewidgetandtags. - If
200 OK: Inject the returned JSON into<script id="onpage-product-schema-..." type="application/ld+json">. - If
204 No Content(or timeout): Render the HTML page without the Feefo JSON-LD block and allow subsequent requests to fetch it once generated. - Return the completed HTML document.
Integration Best Practices
- Enforce strict HTTP timeouts (~100ms): Because SSR requests run during server page generation, upstream latency can impact Time to First Byte (TTFB). Set a strict timeout (recommended ~100ms). If the request times out or fails, abort and render the page without the JSON-LD block.
- Rely on the safe client-side fallback: If the SSR request returns
204or times out, your site is unaffected—the embedded client-side Feefo widget automatically detects the missing scriptidand injects Schema.org JSON-LD in the browser. - Match widget type and tags: Always send the exact same
widgetvalue andtagsto the SSR API as your on-page Feefo widget so server-rendered structured data matches visible reviews. - Do not alter review data: Insert the Schema.org JSON payload verbatim without modifying ratings, review counts, author names, or review text.
Quick Reference Summary
| Endpoint | Required Params | Optional Params | Returns |
|---|---|---|---|
GET /widgets-review-service/ssr/product | slug, widget, + at least one of: sku, parent_sku, or tags=SERIES:<val> | schema_id, tags (key:value, repeatable) | Schema.org Product |
GET /widgets-review-service/ssr/service | slug, widget | tags (key:value, repeatable) | Schema.org Organization |
Updated about 1 hour ago
