---
title: "Rotate the public key"
method: POST
path: "/v1/sites/{siteId}/keys/rotate"
tags: ["Keys"]
---

# Rotate the public key

`POST /v1/sites/{siteId}/keys/rotate`

## Request

- Base URL: `https://api.ironfang.com/analytics`
- URL: `https://api.ironfang.com/analytics/v1/sites/{siteId}/keys/rotate`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Mints a new public collection key. The key it replaces stays accepted for 24 hours so pages cached with the old snippet keep working; a key that was already retiring is revoked, so at most two keys are ever accepted. Public keys are not secrets and can only ever ask to record for their own site. With an `Idempotency-Key`, a retry rotates once and returns the first answer; a partner integration's managed key must send one. Needs analytics.sites.write.

## Headers

- `Idempotency-Key` string

## Response `200`

The site with its keys after rotation, or the stored answer to a retry

- SiteDetail
  - `config` ConfigVersion, required
    - `config` SiteConfig, required: What the site's recorder may capture. Whatever this says, anything that looks like a payment card number (13 to 19 digits passing the Luhn check) is masked wherever it appears, and card, CVV, password and one-time-code fields are blocked.
      - `analytics` object: Session analytics, from SDK 0.6.0. Sessions are the root: a recording belongs to its session, so a site records only while it follows sessions, and may follow sessions without recording. The site's consent mode and excluded addresses apply as they do to recording.
        - `console_errors` boolean: Add console.error calls to sessions (SDK 0.7.0), their arguments serialised safely and scrubbed as error messages are. A version stored before this switch reads as false.
        - `enabled` boolean: Report every eligible visitor's pages from page load, recorded or not. Must be true while recording.enabled is (422 otherwise). A version stored before this rule that records reads as true.
        - `errors` boolean: Add uncaught errors and unhandled rejections to sessions.
        - `request_sample_percent` integer: The share of successful requests kept, decided per request in the browser. Failures are never sampled. A session says the share it was kept at, and how many were left out.
        - `requests` boolean: Add requests that fail (an answer of 400 or above, no answer, a timeout, a resource that did not load), that the page aborted, or that take 5 seconds or longer, to sessions.
        - `successful_requests` boolean: Add the rest, quick successes, to sessions too (SDK 0.7.0). A version stored before this switch reads as false.
      - `recording` object
        - `allowed_query_parameters` string[]: Query parameters whose values are kept in recorded URLs while record_all_query_parameters is off; all others are removed.
        - `block_selectors` string[]
        - `checkpoint_interval_seconds` integer
        - `consent` 'opt_out' | 'required': opt_out records from page load unless the page opts the visitor out with setConsent({replay: false}), which the browser remembers. required records nothing until the page grants replay consent; the site's snippet then carries data-consent="required" so nothing is requested before it.
        - `enabled` boolean
        - `excluded_ip_ranges` string[]: Visitor addresses that are never recorded, such as the site owner's own networks: public IPv4 or IPv6 addresses, or CIDR ranges such as 203.0.113.0/24 or 2001:db8:1:2::/64. A visitor inside one is refused at admission, and a recording already open from there does not continue. The list is not sent to pages; the collector's GET /v1/address tells a browser its own address and the range to add for it.
        - `mask_inputs` boolean: Mask every form field's value and text typed into an editable region.
        - `mask_selectors` string[]
        - `mask_text` boolean: Mask every text node; unmask_selectors then expose reviewed static text.
        - `max_compressed_mib` integer
        - `max_duration_minutes` integer
        - `record_all_query_parameters` boolean: Keep every query value in recorded URLs except those in removed_query_parameters. Off, only allowed_query_parameters keep theirs. Fragments are removed either way. Needs SDK 0.2.1 or later; older recorders keep only the allowed parameters.
        - `removed_query_parameters` string[]: Query parameters whose values are removed while record_all_query_parameters is on, such as a token or an email address.
        - `sample_rate_percent` integer
        - `unmask_selectors` string[]
    - `created_at` string, date-time, required
    - `created_by` string, required: The user id, or key:<id> for a platform key.
    - `id` string, uuid, required
    - `sha256` string, required: SHA-256 of the stored configuration document.
    - `site_id` string, uuid, required
    - `version` integer, required
  - `keys` SiteKey[], required: The keys currently accepted, newest first.
    - `created_at` string, date-time, required
    - `id` string, uuid, required
    - `key` string, required: Public collection key; safe to publish.
    - `retires_at` string, date-time
    - `site_id` string, uuid, required
    - `state` 'active' | 'retiring', required
  - `origins` Origin[], required
    - `checked_at` string, date-time
    - `created_at` string, date-time, required
    - `dns_record` object: The TXT record to publish; absent for loopback origins.
      - `name` string, required
      - `type` 'TXT', required
      - `value` string, required
    - `id` string, uuid, required
    - `origin` string, required
    - `site_id` string, uuid, required
    - `verification` 'pending' | 'verified' | 'not_required', required
    - `verification_token` string
    - `verified_at` string, date-time
  - `site` Site, required
    - `config_version` integer, required: The configuration version in force.
    - `created_at` string, date-time, required
    - `disabled_at` string, date-time
    - `external_id` string, nullable, required: Your own identifier for the site, when one was given at creation.
    - `id` string, uuid, required
    - `name` string, required
    - `organisation_id` string, uuid, required
    - `retention_days` integer, required: Days a recording is kept.
    - `session_retention_days` integer, required: Days session history is kept, never fewer than retention_days. A session loses its IP address, user agent and visitor id after retention_days.
    - `status` 'active' | 'disabled', required
    - `timezone` string, required
    - `updated_at` string, date-time, required
    - `version` integer, required: Name this in a PATCH.

## Other responses

- `400`: The body is not valid JSON of the documented shape (`invalid_json`); the Idempotency-Key is malformed (`invalid_idempotency_key`); or a partner integration sent none (`idempotency_key_required`).
- `401`: 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`).
- `403`: 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`).
- `404`: No such object in this organisation (`not_found`).
- `409`: The Idempotency-Key was used for a different request (`idempotency_conflict`).
- `429`: Too many requests; wait for Retry-After (`rate_limited`).

---

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