---
title: "Confirm an edit request and apply it"
method: POST
path: "/api/edit-confirm"
tags: ["Edits"]
---

# Confirm an edit request and apply it

`POST /api/edit-confirm`

## Request

- Base URL: `https://curlship.com`
- URL: `https://curlship.com/api/edit-confirm`
- Auth: none declared

For a domain proof, this re-fetches every affected site and checks the token before writing anything. For an email proof the same thing happens when the recipient opens the mailed link and presses the confirm button (the link itself only displays the pending change — mail scanners fetch links, and the token is single use), so calling this endpoint by hand is only needed if you kept the token.

On success: the change is written, every field is logged with its old value, the registered address is emailed an undo link valid 7 days, and a URL change resets the badge to unverified.

**A metadata refresh takes two calls here.** The first returns `applied: false`, `status: "preview"`, the proposed `changed` values and an `apply` digest, and writes NOTHING — do not read a 200 as "done", check `applied`. Send the digest back as `apply` to save it. The page is re-read on apply and the digest re-checked, so if it changed in between you get a fresh preview instead of a write nobody saw. URL and email changes stay one-step: those values came from you and are not re-read.

## Request body

- object
  - `request_id` integer, required
  - `token` string, required
  - `apply` string: Metadata refresh only. The digest returned by the preview call. Omit it to get the preview; send it back to write. Ignored for url/email changes.

## Response `200`

Applied, OR — for a metadata refresh sent without a matching `apply` digest — a preview that wrote nothing. Check `applied`.

- object
  - `ok` boolean
  - `applied` boolean: false means nothing was written — this is a preview.
  - `status` 'preview': Present only on a preview.
  - `changed` object, nullable: Preview only: field -> {from, to}. null when nothing would change.
  - `apply` string: Preview only: send this back to write.
  - `listing_id` integer: Preview only.
  - `url` string: Preview only: the page that was read.
  - `then` object: Preview only: the exact follow-up call that writes.
  - `message` string
  - `listing` object
    - `id` integer
    - `url` string, uri
    - `tier` 'free' | 'bronze' | 'silver' | 'gold' | 'platinum'
    - `title` string, nullable
    - `description` string, nullable
    - `image` string, uri, nullable
    - `has_badge` boolean: True if a dofollow link back to curlship.com was found on the site.
    - `created_at` string, date-time, nullable: When the listing was created, UTC.

## Other responses

- `400`: Missing request_id or token
- `404`: No request with that id
- `409`: Bad token, expired, already used, or proof not satisfied
- `429`: Rate limit exceeded. Retry-After is the wait in seconds. RateLimit-Policy names the window that was hit. RateLimit repeats that name with r=0 and t equal to Retry-After. Windows: submit 10 per 3600s, verify 30 per 3600s, checkout 30 per 3600s, edit 5 per 3600s per IP, edit-listing 3 per 86400s per listing.

---

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