---
title: "Move a page to the corroboration registry"
method: POST
path: "/surfaces/{id}/convert-to-corroboration"
tags: ["Surfaces"]
---

# Move a page to the corroboration registry

`POST /surfaces/{id}/convert-to-corroboration`

## Request

- Base URL: `https://api.epovest.com/v1`
- URL: `https://api.epovest.com/v1/surfaces/{id}/convert-to-corroboration`
- Auth: HTTP bearer

For a line filed on the wrong side, or a page whose final say moved to someone else. Nothing
is retyped: `url`, `label` and `notes` travel, and the publication date stays unknown rather
than guessed. The surface goes to the trash with its alignment journal, and the reverse move
exists, so a replay finds the same line instead of duplicating it (`201` on creation, `200`
when the page already slept in the registry and was put back live). Manager or above.

## Response `200`

The corroboration already existed and was put back live.

- CorroborationEnvelope
  - `corroboration` Corroboration, required
    - `id` string, uuid, required
    - `project_id` string, uuid, required
    - `url` string, required: The exact page.
    - `domain` string, required: The registrable domain the page sits on, derived from the address by the same normalizer as the Atlas. Correcting the `url` always recomputes it.
    - `label` string, nullable, required
    - `notes` string, nullable, required
    - `published_on` string, date, nullable, required: The day the page was PUBLISHED, distinct from `created_at`, the day it was recorded. It is the publication date that means something against the citation curves.
    - `author` string, nullable, required
    - `request_channel` 'available' | 'none' | 'unknown', required: Whether someone can be asked to change the page: `available` (a contact or a process exists), `none` (nobody to ask) or `unknown` (not filled in, the default). Three states, because "no channel" and "not filled in" are two different facts.
    - `monitoring` 'off' | 'daily' | 'weekly' | 'monthly', required: The cadence of the automatic watching of a corroboration. Each executed check runs the same pass as the on-demand check and debits the prepaid balance per executed check.
    - `monitoring_paused` boolean, required: True while the passes wait on the balance, the cadence kept: a top-up resumes them as they were.
    - `archived` boolean, required
    - `page_check` PageCheck, required: The latest reading of the page, refreshed by `POST /corroborations/{id}/verify` and by the watching cadence.
      - `readability` 'pending' | 'html' | 'unreadable' | 'blocked' | 'unreachable' | 'no_page', required
      - `checked_at` string, date-time, nullable, required
      - `http_status` integer, nullable, required
      - `mention` object, required: The finding on the passage around the brand: `unchanged`, `changed` (the passage moved, worth re-reading), `figures` (it moved on NUMBERS only, such as a rank or a counter, so `changed_at` stays where it was) or `gone` (the page did not answer).
        - `finding` 'unchanged' | 'changed' | 'figures' | 'gone' | 'null', nullable
        - `excerpt` string, nullable
        - `excerpt_before` string, nullable: The passage as it stood BEFORE `changed_at`, so comparing the two texts says what moved without reading the whole page again.
        - `extractor` string, nullable
        - `changed_at` string, date-time, nullable
      - `link` object, nullable, required: The finding on the links of the page towards the addresses of the brand.
        - `finding` 'unchanged' | 'changed' | 'gone' | 'none'
        - `changes` unknown[]
          - unknown
        - `outbound` integer, nullable
        - `noindex` boolean, nullable
        - `page_nofollow` boolean, nullable
        - `canonical_elsewhere` string, nullable
        - `links` LinkSighting[]
          - `url` string
          - `kind` string, nullable
          - `anchor` string, nullable
          - `rel` string[]: The rel tokens of the link, among `nofollow`, `sponsored` and `ugc`.
          - `html_target` string, nullable
          - `title` string, nullable
          - `in_main_content` boolean, nullable
          - `nature` string, nullable
          - `final_url` string, nullable
          - `hops` integer, nullable
          - `final_status` integer, nullable
          - `first_seen` string, date-time
          - `last_seen` string, date-time
          - `changed_at` string, date-time, nullable
    - `created_at` string, date-time, required

## Other responses

- `201`: The corroboration, recorded.
- `401`: `unauthenticated`: missing, unknown or revoked key.
- `403`: `insufficient_scope`: the credential may not do this, either because the key lacks the scope, or, on a one-click connection, because the person lacks the role the action needs (manager, or owner to start, pause and top up). On that path, read it as "this person may not do this" and tell them which role the action needs.
- `404`: `not_found`: unknown for this account.
- `422`: `own_domain`: the own site of the brand stays a surface. The other refusals of the registry answer with their own slug.
- `429`: `rate_limited`: 120 requests per minute per credential, sliding window. Retry after `Retry-After` seconds.

---

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