From a4fc9e2d76d1b320950424840486ee1f2e80b6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karlo=20=C5=A0imunovi=C4=87?= Date: Wed, 29 Apr 2026 16:15:06 +0200 Subject: [PATCH] Add hotspot endpoints documentation This update introduces comprehensive documentation for the Hotspot APIs, detailing how to list, retrieve, and create hotspots associated with spreads. It includes descriptions of the available fields and their types for different hotspot types. - Added API endpoint for listing hotspots of a spread - Included detailed descriptions for each hotspot field - Documented request and response structures for creating and retrieving hotspots - Explained pagination and error handling for API requests --- source/rest-v2.html.md | 311 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) diff --git a/source/rest-v2.html.md b/source/rest-v2.html.md index 1d1757ebb59..5faa078aacd 100644 --- a/source/rest-v2.html.md +++ b/source/rest-v2.html.md @@ -2039,6 +2039,317 @@ Both 'links' and 'products' allow the fields below: | ----- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | icons | Boolean | No | Show or hide hotspot icons for extracted hotspot. This setting is not applicable to hotspots extracted from PDF annotations (those are defined in the annotation itself) | +# Hotspot Endpoints + +Hotspots are interactive areas placed on spread pages. Each hotspot has a type that determines its behavior and the additional fields returned in the response. All coordinates and dimensions are expressed as a fraction of the spread size (values between 0 and 1). + +## List all hotspots of a spread + +```shell +curl "https://api.publitas.com/v2/spreads/42/hotspots" \ + -H "Authorization: ApiKey " +``` + +> The above command returns JSON structured like this: + +```json +{ + "hotspots": [ + { + "id": 1, + "type": "external_link", + "top": 0.1, + "left": 0.2, + "width": 0.15, + "height": 0.08, + "icon_left": 0.5, + "icon_top": 0.5, + "show_indication": true, + "tab_index": null, + "z_index": 0, + "embedded_content": false, + "dynamic": false, + "product_theme_id": null, + "rotation": 0.0, + "url": "https://example.com", + "popup_max_width": null, + "popup_max_height": null + } + ] +} +``` + +### HTTP Request + +`GET https://api.publitas.com/v2/spreads//hotspots` + +### URL Parameters + +| Parameter | Description | +| --------- | ------------------------------- | +| Spread ID | The ID of a specific spread | + +This endpoint supports [pagination](#understanding-pagination). Results are ordered by page number. + +### Response fields + +The response returns an array of hotspot objects. All hotspot types share the following base fields: + +| Field | Type | Description | +| ----------------- | ------------ | -------------------------------------------------------- | +| `id` | Integer | Hotspot ID | +| `type` | String | Hotspot type (see below) | +| `top` | Float | Top offset as a fraction of spread height (0–1) | +| `left` | Float | Left offset as a fraction of spread width (0–1) | +| `width` | Float | Width as a fraction of spread width (0–1) | +| `height` | Float | Height as a fraction of spread height (0–1) | +| `icon_left` | Float | Horizontal center of the hotspot icon (0–1) | +| `icon_top` | Float | Vertical center of the hotspot icon (0–1) | +| `show_indication` | Boolean | Whether the hotspot indication icon is visible | +| `tab_index` | Integer/null | Accessibility tab order | +| `z_index` | Integer | Stacking order relative to other hotspots on the spread | +| `embedded_content`| Boolean | Whether the hotspot renders its content inline | +| `dynamic` | Boolean | `true` shows a full product card overlay; `false` acts as a transparent link | +| `product_theme_id`| Integer/null | Product theme ID for product-type hotspots | +| `rotation` | Float | Rotation in degrees | + +Additional fields are included depending on `type`: + +**`external_link`** + +| Field | Type | Description | +| ----------------- | ------------ | --------------------------------------------- | +| `url` | String | Target URL | +| `popup_max_width` | Integer/null | Maximum popup width in pixels | +| `popup_max_height`| Integer/null | Maximum popup height in pixels | + +**`page_reference`** + +| Field | Type | Description | +| ------------- | ------- | ------------------------------------ | +| `page_number` | Integer | Publication page number to link to | + +**`video`** + +| Field | Type | Description | +| -------------------------------- | ------------ | ------------------------------------------------ | +| `video_id` | String/null | Video ID (for hosted providers) | +| `video_provider` | String/null | Video provider (e.g. `youtube`, `vimeo`) | +| `video_url` | String/null | Direct video URL or file path | +| `video_type` | String/null | Video type | +| `video_autoplay` | Boolean | Whether the video autoplays on open | +| `video_show_preview` | Boolean/null | Whether a preview thumbnail is shown | +| `video_loop` | Boolean | Whether the video loops | +| `video_start_time` | Integer/null | Start time in seconds | +| `video_overlay_content` | Boolean | Whether the video overlays other content | +| `video_show_accessibility_controls` | Boolean | Whether accessibility controls are shown | +| `accessibility_text` | String/null | Accessible label for the video | + +**`image`** + +| Field | Type | Description | +| -------------------- | ------------ | ----------------------------------------------------- | +| `url` | String | Image URL | +| `image_alt_text` | String/null | Alt text for the image | +| `content_fit_mode` | String/null | How the image is fitted (`cover`, `contain`, etc.) | +| `image_show_lightbox`| Boolean | Whether clicking opens the image in a lightbox | +| `show_tooltip` | Boolean | Whether to show a tooltip | +| `corner_radius` | Integer/null | Corner radius in pixels | +| `opacity` | Float/null | Opacity (0–1) | +| `image_crop_state` | Object/null | Crop state metadata | +| `style_json` | Object/null | Custom style overrides | +| `background_color` | String/null | Background color (hex); `null` when disabled | + +**`slideshow`** + +| Field | Type | Description | +| -------- | ----- | ------------------------ | +| `slides` | Array | Array of slide objects (see below) | + +Each slide object contains: + +| Field | Type | Description | +| ------------------- | ------------ | ---------------------------------- | +| `id` | Integer | Slide ID | +| `hotspot_id` | Integer | Parent hotspot ID | +| `position` | Integer | Display order | +| `url` | String/null | External image URL | +| `file_path` | String/null | Hosted file path | +| `file_hosted` | Boolean | Whether the file is hosted | +| `file_url` | String/null | Absolute URL to the hosted file | +| `original_filename` | String/null | Original upload filename | +| `alt_text` | String/null | Accessible alt text for the slide | + +**`product`** + +| Field | Type | Description | +| ---------- | ----- | -------------------------------------------------------------- | +| `products` | Array | Array of product objects serialized via the V2 Product schema | + +## Get a specific hotspot + +```shell +curl "https://api.publitas.com/v2/spreads/42/hotspots/1" \ + -H "Authorization: ApiKey " +``` + +> The above command returns JSON structured like this: + +```json +{ + "hotspot": { + "id": 1, + "type": "external_link", + "top": 0.1, + "left": 0.2, + "width": 0.15, + "height": 0.08, + "icon_left": 0.5, + "icon_top": 0.5, + "show_indication": true, + "tab_index": null, + "z_index": 0, + "embedded_content": false, + "dynamic": false, + "product_theme_id": null, + "rotation": 0.0, + "url": "https://example.com", + "popup_max_width": null, + "popup_max_height": null + } +} +``` + +### HTTP Request + +`GET https://api.publitas.com/v2/spreads//hotspots/` + +### URL Parameters + +| Parameter | Description | +| ---------- | ----------------------------------- | +| Spread ID | The ID of a specific spread | +| Hotspot ID | The ID of a specific hotspot | + +Returns 404 if the hotspot does not exist on the requested spread or belongs to a different spread. + +## Create a hotspot + +```shell +curl "https://api.publitas.com/v2/spreads/42/hotspots" \ + -H "Authorization: ApiKey " \ + -H "Content-Type: application/json" \ + --data '{ + "type": "external_link", + "top": 0.1, + "left": 0.2, + "width": 0.15, + "height": 0.08, + "url": "https://example.com" + }' +``` + +> The above command returns JSON structured like this: + +```json +{ + "hotspot": { + "id": 99, + "type": "external_link", + "top": 0.1, + "left": 0.2, + "width": 0.15, + "height": 0.08, + "icon_left": 0.5, + "icon_top": 0.5, + "show_indication": true, + "tab_index": null, + "z_index": 0, + "embedded_content": false, + "dynamic": false, + "product_theme_id": null, + "rotation": 0.0, + "url": "https://example.com", + "popup_max_width": null, + "popup_max_height": null + } +} +``` + +### HTTP Request + +`POST https://api.publitas.com/v2/spreads//hotspots` + +### URL Parameters + +| Parameter | Description | +| --------- | ------------------------------- | +| Spread ID | The ID of a specific spread | + +### Request body parameters + +**Core fields (all types)** + +| Field | Type | Required | Description | +| ----------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------- | +| `type` | String | Yes | Hotspot type: `external_link`, `page_reference`, `video`, `image`, `slideshow`, or `product` | +| `top` | Float | Yes | Top offset as a fraction of spread height (0–1) | +| `left` | Float | Yes | Left offset as a fraction of spread width (0–1) | +| `width` | Float | Yes | Width as a fraction of spread width (0–1) | +| `height` | Float | Yes | Height as a fraction of spread height (0–1) | +| `show_indication` | Boolean | No | Whether the hotspot indication icon is visible | +| `tab_index` | Integer | No | Accessibility tab order | +| `embedded_content`| Boolean | No | Whether the hotspot renders its content inline | + +**`external_link` fields** + +| Field | Type | Required | Description | +| ----------------- | ------- | -------- | ---------------------------------- | +| `url` | String | Yes | Target URL | +| `popup_max_width` | Integer | No | Maximum popup width in pixels | +| `popup_max_height`| Integer | No | Maximum popup height in pixels | + +**`page_reference` fields** + +| Field | Type | Required | Description | +| ------------- | ------- | -------- | ---------------------------------- | +| `page_number` | Integer | Yes | Publication page number to link to | + +**`video` fields** + +| Field | Type | Required | Description | +| -------------------------------- | ------- | -------- | ------------------------------------------------------ | +| `video_url` | String | Yes | Video URL or file path | +| `video_type` | String | No | Video type | +| `video_provider` | String | No | Video provider (e.g. `youtube`, `vimeo`) | +| `video_autoplay` | Boolean | No | Whether the video autoplays on open | +| `video_loop` | Boolean | No | Whether the video loops | +| `video_show_preview` | Boolean | No | Whether a preview thumbnail is shown | +| `video_start_time` | Integer | No | Start time in seconds | +| `video_overlay_content` | Boolean | No | Whether the video overlays other content | +| `video_show_accessibility_controls` | Boolean | No | Whether accessibility controls are shown | +| `accessibility_text` | String | No | Accessible label for the video | + +**`image` fields** + +| Field | Type | Required | Description | +| -------------------- | ------- | -------- | ------------------------------------------------------- | +| `url` | String | Yes | Image URL | +| `image_alt_text` | String | No | Alt text for the image | +| `image_add_alt_text` | Boolean | No | Whether to include alt text in the response | +| `content_fit_mode` | String | No | How the image is fitted (`cover`, `contain`, etc.) | +| `image_show_lightbox`| Boolean | No | Whether clicking opens the image in a lightbox | +| `show_tooltip` | Boolean | No | Whether to show a tooltip | +| `corner_radius` | Integer | No | Corner radius in pixels | +| `opacity` | Float | No | Opacity (0–1) | + +### Response codes + +| Code | Description | +| ---- | ---------------------------------- | +| 201 | Hotspot created successfully | +| 422 | Validation errors in request body | + # Errors > When there is an error the command returns JSON structured like this: