---
title: "Replace the file's hotspots (Pro)"
method: PUT
path: "/api/v1/files/{uuid}/hotspots"
tags: ["Files"]
---

# Replace the file's hotspots (Pro)

`PUT /api/v1/files/{uuid}/hotspots`

## Request

- Base URL: `https://everypage.co`
- URL: `https://everypage.co/api/v1/files/{uuid}/hotspots`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://everypage.co/oauth/authorize`, token URL `https://everypage.co/oauth/token`, scopes: `files:write`)

Whole-set replace, not a merge - omitted hotspots are deleted. Owner only, Pro plan, scope `files:write`. Rects are normalised 0-1 against the page box. Max 300 per file, 30 per page. `page` payloads must target a page that exists, and `image`/`audio` payloads reference an assetId owned by the same file.

## Request body

- object
  - `hotspots` object[]
    - `page` integer
    - `x` number
    - `y` number
    - `w` number
    - `h` number
    - `kind` 'link' | 'page' | 'video' | 'image' | 'audio'
    - `payload` object

## Response `200`

The stored set, with server-assigned uuids

- object
  - `hotspots` object[]

## Other responses

- `400`: Invalid hotspot set
- `401`: No or invalid API key, OAuth token, manage token or claim token (code `missing_token` or `invalid_token`).
- `403`: Not the owner (code `forbidden`), an OAuth token missing the required scope (`insufficient_scope`, with a `WWW-Authenticate` challenge naming it), a feature above your plan (`plan_required`), a plan limit reached such as file slots or the per-file asset cap (`forbidden`), or - on the two manage-token operations - a token acting at the free tier on a plan-gated field.
- `404`: Unknown id, or a file you do not own on routes where 404 replaces 403 (code `not_found`).
- `413`: The upload (or the PDF a Word/PowerPoint file converted to) is above your plan's size cap - 20MB Free, 200MB Basic, 2GB Pro - or a JSON body is over its fixed cap (1MB for settings and hotspots, 64KB for variants and claims) (code `payload_too_large`).
- `429`: Over the limit - 120 requests per minute per Authorization value on /api/v1 (webhook test 10/min; the Canva lane 30/min per IP). Code `rate_limited`; wait for `Retry-After`.

---

[API](https://skmtc.dev/everypage/apis/everypage-api.md) · [All operations](https://skmtc.dev/everypage/apis/everypage-api/llms.txt) · [OpenAPI document](https://skmtc.dev/everypage/apis/everypage-api/revisions/e6674f903456?raw)
