openapi: 3.2.0 info: title: Ironfang Analytics Heatmaps API version: 0.1.0 summary: Sites, origins, public keys and capture settings for session replay and web analytics. description: 'Ironfang Analytics follows each visit to your website as a session: the pages a visitor saw, in every tab, with how long they stayed, the errors and failed requests they met, the events your pages tracked, and the recordings that let you replay it, live or afterwards.' contact: name: Ironfang email: hello@ironfang.uk url: https://ironfang.com/contact termsOfService: https://ironfang.com/legal/terms license: name: Proprietary - use governed by the Ironfang terms of service url: https://ironfang.com/legal/terms servers: - url: https://api.ironfang.com/analytics security: - apiKey: [] - bearerAuth: [] tags: - name: Heatmaps description: Totals of where visitors click, how far they scroll, how long each part of a page is on screen and where the pointer goes, across the recorded visits to one page. Computed from recordings, so they keep what recordings keep and need analytics.sessions.read. Every figure is per page visit; horizontal positions count from the centre of the viewport. paths: /v1/sites/{siteId}/pages: parameters: - $ref: '#/components/parameters/SiteId' get: tags: - Heatmaps operationId: listHeatmapPages summary: List pages with visits description: The site's pages that recorded visits showed in a period, most visited first, by device. A recording is indexed shortly after it ends. Needs analytics.sessions.read. parameters: - $ref: '#/components/parameters/HeatmapFrom' - $ref: '#/components/parameters/HeatmapTo' - name: limit in: query required: false schema: type: integer minimum: 1 maximum: 500 default: 100 responses: '200': description: Pages content: application/json: schema: type: object required: - from - to - pages properties: from: type: string format: date-time to: type: string format: date-time pages: type: array items: $ref: '#/components/schemas/HeatmapPage' '400': $ref: '#/components/responses/InvalidQuery' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' /v1/sites/{siteId}/pages/changes: parameters: - $ref: '#/components/parameters/SiteId' get: tags: - Heatmaps operationId: listLayoutChanges summary: List the days a page's layout changed description: 'Each day whose most common layout differs from the previous day the page was visited: when the page changed, for comparing the week before with the week after. Days are in tz, or the site''s time zone. Needs analytics.sessions.read.' parameters: - $ref: '#/components/parameters/HeatmapPath' - name: bucket in: query required: false description: One device; every device when left out. schema: $ref: '#/components/schemas/HeatmapBucket' - $ref: '#/components/parameters/HeatmapFrom' - $ref: '#/components/parameters/HeatmapTo' - name: tz in: query required: false description: An IANA time zone for the days. schema: type: string example: Europe/London responses: '200': description: Layout changes content: application/json: schema: type: object required: - path - timezone - changes properties: path: type: string timezone: type: string changes: type: array items: type: object required: - day - from - to properties: day: type: string format: date from: type: - string - 'null' to: type: - string - 'null' '400': $ref: '#/components/responses/InvalidQuery' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' /v1/sites/{siteId}/heatmaps: parameters: - $ref: '#/components/parameters/SiteId' get: tags: - Heatmaps operationId: getHeatmap summary: Get a page's heatmap description: Attention, scroll reach, clicks and movement for one page and device over a period, from at most 20,000 of its visits (a deterministic sample when there are more), with the visit to draw it over. Fewer than 30 visits is flagged small_sample. Needs analytics.sessions.read. parameters: - $ref: '#/components/parameters/HeatmapPath' - $ref: '#/components/parameters/HeatmapBucketParam' - $ref: '#/components/parameters/HeatmapFrom' - $ref: '#/components/parameters/HeatmapTo' responses: '200': description: Heatmap content: application/json: schema: $ref: '#/components/schemas/Heatmap' '400': $ref: '#/components/responses/InvalidQuery' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' /v1/sites/{siteId}/heatmaps/compare: parameters: - $ref: '#/components/parameters/SiteId' get: tags: - Heatmaps operationId: compareHeatmaps summary: Compare two periods description: One page and device over two periods, with the targets clicked in both and how their rate changed. overlay_valid says both periods have the same most common layout, so a difference overlay on one page means something; across a redesign, show them side by side. Needs analytics.sessions.read. parameters: - $ref: '#/components/parameters/HeatmapPath' - $ref: '#/components/parameters/HeatmapBucketParam' - name: a_from in: query required: true schema: type: string format: date-time - name: a_to in: query required: true schema: type: string format: date-time - name: b_from in: query required: true schema: type: string format: date-time - name: b_to in: query required: true schema: type: string format: date-time responses: '200': description: Comparison content: application/json: schema: type: object required: - a - b - overlay_valid - elements properties: a: $ref: '#/components/schemas/Heatmap' b: $ref: '#/components/schemas/Heatmap' overlay_valid: type: boolean elements: type: array items: type: object required: - selector - a - b - change properties: selector: type: string a: type: number description: Clicks per visit in the first period. b: type: number description: Clicks per visit in the second period. change: type: number '400': $ref: '#/components/responses/InvalidQuery' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' components: parameters: HeatmapPath: name: path in: query required: true description: The page's path, without a query string or fragment. schema: type: string example: /pricing HeatmapFrom: name: from in: query required: false description: The period's start; with to, at most 93 days. Both left out is the seven days to now. schema: type: string format: date-time HeatmapBucketParam: name: bucket in: query required: true schema: $ref: '#/components/schemas/HeatmapBucket' SiteId: name: siteId in: path required: true schema: type: string format: uuid HeatmapTo: name: to in: query required: false description: The period's end, not included. schema: type: string format: date-time responses: NotFound: description: No such object in this organisation (`not_found`). content: application/json: schema: $ref: '#/components/schemas/Error' Forbidden: description: The credential lacks the permission or scope, names another organisation, or belongs to a partner integration that is not active (`forbidden`, `insufficient_scope`, `integration_inactive`). content: application/json: schema: $ref: '#/components/schemas/Error' InvalidQuery: description: An unknown, repeated or malformed query parameter (`invalid_query`). content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized: description: No credential, an invalid one, an expired partner integration key, or a delegated token where none is accepted (`unauthorized`, `invalid_api_key`, `api_key_expired`, `delegated_not_allowed`). content: application/json: schema: $ref: '#/components/schemas/Error' schemas: HeatmapBackground: type: object required: - recording_id - epoch_index - started_at - offset_ms - duration_ms - layout_hash - viewport_width - viewport_height properties: recording_id: type: string format: uuid epoch_index: type: integer started_at: type: string format: date-time offset_ms: type: integer description: Where the visit starts in its recording, in milliseconds from the recording's first event, as the replay player counts them. duration_ms: type: integer description: How long the visit lasted. layout_hash: type: - string - 'null' viewport_width: type: integer viewport_height: type: integer Heatmap: type: object required: - path - bucket - from - to - visits - sampled - small_sample - visibility_known - seconds_on_screen - layouts - background - backgrounds - bands - clicks - moves properties: path: type: string bucket: $ref: '#/components/schemas/HeatmapBucket' from: type: string format: date-time to: type: string format: date-time visits: type: integer description: Page visits in the period. sampled: type: integer description: The visits the totals come from, at most 20000. small_sample: type: boolean description: Fewer than 30 visits. visibility_known: type: number description: The share of visits whose time excludes a hidden tab (SDK 0.5.0). seconds_on_screen: type: object required: - mean - median properties: mean: type: number median: type: number layouts: type: array description: The layouts seen, most common first. items: type: object required: - hash - visits properties: hash: type: - string - 'null' visits: type: integer background: description: The visit whose page at load the heatmap is drawn over; play it through the playback routes. anyOf: - $ref: '#/components/schemas/HeatmapBackground' - type: 'null' backgrounds: type: array description: 'The visits the heatmap can be drawn over, background first: of the most common layout, at a width near the period''s median, and of those the ones that scrolled furthest. At most 5.' items: $ref: '#/components/schemas/HeatmapBackground' bands: type: object required: - px - attention_share - ms_per_visit - reach properties: px: type: integer description: The height of a band. attention_share: type: array items: type: number description: Per band from the top, the share of a visit's time it was on screen. ms_per_visit: type: array items: type: number reach: type: array items: type: number description: Per band, the share of visits that scrolled to its bottom. clicks: type: object required: - per_visit - fixed_per_visit - cell_px - cells - fixed_cells - elements properties: per_visit: type: number fixed_per_visit: type: number description: Clicks on fixed or sticky elements, which belong to the screen rather than a place on the page. cell_px: type: integer cells: type: array items: $ref: '#/components/schemas/HeatmapCell' fixed_cells: type: array items: $ref: '#/components/schemas/HeatmapCell' elements: type: array description: The targets most clicked, named without text. items: type: object required: - selector - clicks - per_visit - fixed - located - offsets - cells properties: selector: type: string clicks: type: integer per_visit: type: number fixed: type: boolean description: Whether most of its clicks landed on it while fixed or sticky. located, offsets and cells cover those clicks only. located: type: integer description: How many of its clicks carry where within the target they landed (SDK 0.5.0). offsets: type: array description: A sample of the located clicks, where within the target each landed, 0 to 10000 across and down. items: type: array items: type: integer minItems: 2 maxItems: 2 cells: type: array description: The located clicks in the page grid (the fixed grid when fixed), per visit. Drawing them inside the target's box instead, take these out of cells or fixed_cells so they are not counted twice. items: $ref: '#/components/schemas/HeatmapCell' moves: type: object required: - cell_px - cells properties: cell_px: type: integer cells: type: array items: $ref: '#/components/schemas/HeatmapCell' description: Milliseconds per visit the pointer rested in each cell. HeatmapBucket: type: string enum: - mobile - tablet - desktop description: By viewport width when the visit began, under 768, under 1280, and wider. Error: type: object required: - error properties: error: type: object required: - code - message - docs properties: code: type: string description: Stable machine-readable code. message: type: string description: Human-readable explanation; do not parse. docs: type: string format: uri request_id: type: string HeatmapPage: type: object required: - path - visits - mobile - tablet - desktop properties: path: type: string visits: type: integer mobile: type: integer tablet: type: integer desktop: type: integer HeatmapCell: type: array description: '[x, y, value]: x cells from the centre of the viewport (negative to the left), y cells from the top of the page (of the viewport for fixed clicks), and the value per visit.' items: type: number minItems: 3 maxItems: 3 securitySchemes: apiKey: type: http scheme: bearer bearerFormat: if_live_ platform API key description: 'A platform API key minted in the portal. Its scopes are its permissions - `analytics:sites:read`, `analytics:sites:write` and the other `analytics:` scopes, or `analytics:*` - and it acts only in the organisation it was minted for. Keys without the scope a route needs are refused with 403. ' bearerAuth: type: http scheme: bearer bearerFormat: Warden JWT description: 'A Warden user token. Each route also requires a tenant permission in the acting tenant (`X-Ironfang-Tenant`), resolved live from Warden, which each operation names: sites need `analytics.sites.read` to read and `analytics.sites.write` to change; sessions, recordings and heatmaps need `analytics.sessions.read`, and deleting a session or a recording `analytics.sessions.delete`. A missing permission is 403; a permission lookup failure is 503. ' externalDocs: description: Ironfang Analytics documentation url: https://ironfang.com/analytics/docs