# Render a product Rich Snippet

> Returns visible product-rating HTML and matching Product JSON-LD.

Breadcrumb: Storefront API › Render a product Rich Snippet
Docs index: https://docs.cevoid.com/developers/llms.txt

`GET https://api.widget.cevoid.com/v1/products/{productRef}/rich-snippet`

Returns visible product-rating HTML and matching Product JSON-LD.

## Authorizations

Bearer token in the Authorization header: `Authorization: Bearer <key>` (Cevoid publishable key).

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `productRef` | `string` | Yes | Stable Cevoid product or variant id, external product reference, URL slug, or `auto` with a referer. Length: `1 to 256`. Example: `prd_linen_shirt`. |

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `market` | `string` | No | Workspace market short id. When omitted, Cevoid infers the market from the referer URL. Length: `1 to 128`. Example: `mar_sweden`. |
| `language` | `string` | Yes | Language used for market-specific product presentation, such as `sv` or `en-US`. Length: `1 to 64`. Example: `sv-SE`. |
| `referer` | `string<uri>` | No | Product page URL used for `auto` product resolution and optional market inference. Maximum length: `2048`. Example: `https://shop.example.com/products/linen-shirt`. |

## Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `referer` | `string<uri>` | No | Product page URL used when the referer query parameter is omitted. Maximum length: `2048`. Example: `https://shop.example.com/products/linen-shirt`. |

## Response

### 200: Successful response

`application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `html` | `string` | Yes | Visible aggregate-rating HTML rendered from the same projection snapshot as jsonLd. Minimum length: `1`. Example: `<div class="cevoid-rating">Rated 4.8 out of 5 from 24 reviews</div>`. |
| `jsonLd` | `object` | Yes |  |
| `jsonLd.@context` | `enum<string>` | Yes | Schema.org vocabulary URL. Allowed value: `https://schema.org`. Example: `https://schema.org`. |
| `jsonLd.@type` | `enum<string>` | Yes | Schema.org entity type. Allowed value: `Product`. Example: `Product`. |
| `jsonLd.@id` | `string<uri>` | Yes | Canonical product entity identifier. Example: `https://shop.example.com/products/linen-shirt#cevoid-product`. |
| `jsonLd.url` | `string<uri>` | Yes | Canonical product page URL. Example: `https://shop.example.com/products/linen-shirt`. |
| `jsonLd.name` | `string` | Yes | Market-specific product title. Example: `Linen Shirt`. |
| `jsonLd.image` | `string<uri>` | No | Market-specific primary product image URL. Example: `https://cdn.cevoid.com/products/linen-shirt.jpg`. |
| `jsonLd.brand` | `object` | No | Product brand when available. |
| `jsonLd.brand.@type` | `enum<string>` | Yes | Allowed value: `Brand`. Example: `Brand`. |
| `jsonLd.brand.name` | `string` | Yes | Example: `Example Apparel`. |
| `jsonLd.sku` | `string` | No | Product SKU when available. Example: `LINEN-SHIRT-NATURAL-M`. |
| `jsonLd.gtin` | `string` | No | Global Trade Item Number when available. Example: `07350012345678`. |
| `jsonLd.mpn` | `string` | No | Manufacturer Part Number when available. Example: `LS-NAT-M`. |
| `jsonLd.aggregateRating` | `object` | Yes |  |
| `jsonLd.aggregateRating.@type` | `enum<string>` | Yes | Allowed value: `AggregateRating`. Example: `AggregateRating`. |
| `jsonLd.aggregateRating.ratingValue` | `number` | Yes | Published average rating. Range: `0 < x`. Example: `4.8`. |
| `jsonLd.aggregateRating.ratingCount` | `integer` | Yes | Published rating count. Range: `0 < x`. Example: `24`. |
| `jsonLd.aggregateRating.bestRating` | `enum<number>` | Yes | Highest possible rating. Allowed value: `5`. Example: `5`. |
| `jsonLd.aggregateRating.worstRating` | `enum<number>` | Yes | Lowest possible rating. Allowed value: `1`. Example: `1`. |
| `projectionVersion` | `enum<number>` | Yes | Version of the authoritative review projection used for both response representations. Allowed value: `1`. Example: `1`. |
| `computedAt` | `string<date-time>` | Yes | ISO 8601 timestamp when the authoritative review projection was computed. Example: `2026-08-01T10:05:00.000Z`. |

Response headers:

| Header | Type | Description |
| --- | --- | --- |
| `Cevoid-Processing-Ms` | `string` | End-to-end request processing time in milliseconds |
| `Cevoid-Request-Id` | `string` | Request identifier for support and tracing |
| `RateLimit-Limit` | `string` | Current rate limit bucket size |
| `RateLimit-Remaining` | `string` | Remaining requests in the current rate limit window |
| `RateLimit-Reset` | `integer` | Seconds until the next request token is available |
| `Cache-Control` | `string` | Browser freshness is 60 seconds. Shared caches are fresh for five minutes and may serve stale content while revalidating for another five minutes. TTL is the only invalidation guarantee; moderation or removal may take up to ten minutes because no active purge is performed. |
| `Vary` | `string` | Workspace credentials and both accepted referer header spellings are included because product and Market context may be inferred from the page URL. |

```json
{
  "html": "<div class=\"cevoid-rating\">Rated 4.8 out of 5 from 24 reviews</div>",
  "jsonLd": {
    "@context": "https://schema.org",
    "@type": "Product",
    "@id": "https://shop.example.com/products/linen-shirt#cevoid-product",
    "url": "https://shop.example.com/products/linen-shirt",
    "name": "Linen Shirt",
    "image": "https://cdn.cevoid.com/products/linen-shirt.jpg",
    "brand": {
      "@type": "Brand",
      "name": "Example Apparel"
    },
    "sku": "LINEN-SHIRT-NATURAL-M",
    "gtin": "07350012345678",
    "mpn": "LS-NAT-M",
    "aggregateRating": {
      "@type": "AggregateRating",
      "ratingValue": 4.8,
      "ratingCount": 24,
      "bestRating": 5,
      "worstRating": 1
    }
  },
  "projectionVersion": 1,
  "computedAt": "2026-08-01T10:05:00.000Z"
}
```

### 400: Bad request

`application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `additional_data` | `object` | No | Optional machine-readable error details. |
| `additional_data.{key}` | `any \| null` | No |  |
| `status` | `integer` | Yes | HTTP status code. Example: `404`. |
| `code` | `string` | Yes | Stable machine-readable error code. Example: `not_found`. |
| `message` | `string` | Yes | Human-readable error description. Example: `Resource not found`. |
| `request_id` | `string` | No | Request identifier for support and tracing. Example: `req_abc123`. |

Response headers:

| Header | Type | Description |
| --- | --- | --- |
| `Cevoid-Processing-Ms` | `string` | End-to-end request processing time in milliseconds |
| `Cevoid-Request-Id` | `string` | Request identifier for support and tracing |
| `RateLimit-Limit` | `string` | Current rate limit bucket size |
| `RateLimit-Remaining` | `string` | Remaining requests in the current rate limit window |
| `RateLimit-Reset` | `integer` | Seconds until the next request token is available |

```json
{
  "additional_data": {
    "property1": null,
    "property2": null
  },
  "status": 400,
  "code": "bad_request",
  "message": "Bad request",
  "request_id": "req_abc123"
}
```

### 401: Unauthorized

`application/json`

Same fields as 400.

Response headers: the same as 400.

```json
{
  "status": 401,
  "code": "unauthorized",
  "message": "Unauthorized",
  "request_id": "req_abc123"
}
```

### 404: Not found

`application/json`

Same fields as 400.

Response headers: the same as 400.

```json
{
  "additional_data": {
    "property1": null,
    "property2": null
  },
  "status": 404,
  "code": "not_found",
  "message": "Resource not found",
  "request_id": "req_abc123"
}
```

### 422: Validation error

`application/json`

Same fields as 400.

Response headers: the same as 400.

```json
{
  "additional_data": {
    "property1": null,
    "property2": null
  },
  "status": 422,
  "code": "validation_error",
  "message": "Validation error",
  "request_id": "req_abc123"
}
```

### 429: Too many requests

`application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `additional_data` | `object` | Yes | Machine-readable rate-limit details. |
| `additional_data.retry_after_seconds` | `integer` | Yes | Range: `0 <= x`. |
| `additional_data.{key}` | `any \| null` | No |  |
| `status` | `integer` | Yes | HTTP status code. Example: `404`. |
| `code` | `string` | Yes | Stable machine-readable error code. Example: `not_found`. |
| `message` | `string` | Yes | Human-readable error description. Example: `Resource not found`. |
| `request_id` | `string` | No | Request identifier for support and tracing. Example: `req_abc123`. |

Response headers:

| Header | Type | Description |
| --- | --- | --- |
| `Cevoid-Processing-Ms` | `string` | End-to-end request processing time in milliseconds |
| `Cevoid-Request-Id` | `string` | Request identifier for support and tracing |
| `RateLimit-Limit` | `string` | Current rate limit bucket size |
| `RateLimit-Remaining` | `string` | Remaining requests in the current rate limit window |
| `RateLimit-Reset` | `integer` | Seconds until the next request token is available |
| `Retry-After` | `integer` | Seconds to wait before retrying the request |

```json
{
  "status": 429,
  "code": "rate_limit_exceeded",
  "message": "Rate limit exceeded",
  "request_id": "req_abc123",
  "additional_data": {
    "retry_after_seconds": 1
  }
}
```

### 500: Internal server error

`application/json`

Same fields as 400.

Response headers: the same as 400.

```json
{
  "status": 500,
  "code": "internal_server_error",
  "message": "Internal server error",
  "request_id": "req_abc123"
}
```

### 503: Service unavailable

`application/json`

Same fields as 400.

Response headers: the same as 400.

```json
{
  "status": 503,
  "code": "service_unavailable",
  "message": "Service unavailable",
  "request_id": "req_abc123"
}
```

## Request example

```bash
curl 'https://api.widget.cevoid.com/v1/products/prd_linen_shirt/rich-snippet?language=sv-SE' \
  -H "Authorization: Bearer ${CEVOID_PUBLISHABLE_KEY}"
```

---

Canonical: https://docs.cevoid.com/developers/storefront-api/storefront-rendering/render-a-product-rich-snippet
