---
title: "Propose a new entry"
method: POST
path: "/api/entity"
tags: ["Proposing changes"]
---

# Propose a new entry

`POST /api/entity`

## Request

- Base URL: `https://verifiedhandles.org`
- URL: `https://verifiedhandles.org/api/entity`
- Auth: HTTP bearer

Queues a new entry for a reviewer. Give it a title and, if it has one, its Wikidata item (`qid`); an entry already on that item is named instead (409), and an item Wikidata has merged into another is refused (409 `qid_merged`, `wikidata_item` names the one it kept: propose on that). A new entry has no images until it exists. While new entries are paused, it answers 503 `not_accepting`. (An account that may create entries itself is not paused.) A short a site redirect holds is refused (409 `short_is_redirect`). With `?check=1` it runs every check and queues nothing: 200 `{ ok: true, check: true }`, or the refusal the real call would answer (an `Idempotency-Key` is not recorded for it). Takes an optional `Idempotency-Key`, so a request whose answer was lost can be sent again safely: the retry gets the first answer back.

## Query parameters

- `check` '1'

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `payload` EditPayload, required: A change to an entry, as the editor sends it. Every field is optional: send only what changes. `handles` and `gallery` are whole lists, which replace the entry’s; `add_handles` / `remove_handles` name single handles instead, applied to the list as it is then, so a change of nothing else needs no base revision and never undoes a handle saved meanwhile. A field the server does not know is ignored.
    - `title` string
    - `subtitle` string, nullable
    - `description` string, nullable: HTML, sanitised on the way in by the same allowlist as every description. At most 64 KiB.
    - `description_source` unknown
    - `wikipedia_credit` object: Credit the description “from Wikipedia”. The server reads the page itself (redirects followed, so a draft since moved is its article), and refuses it unless at least half of the description’s three-word phrases are the page’s lead (`409 credit_text_differs`, with `page` and `share`). Not with `description_source: null`. Errors: `400 bad_wikipedia_title` / `not_english_wikipedia`; `409 wikipedia_page_missing`, `wikipedia_namespace` (not an article or a draft), `wikipedia_section`, `wikipedia_no_lead`, `no_description`, `draft_has_article` (the entry’s item already has an English article, named in `article`: credit that); `502 wikipedia_unreachable`.
      - `page` string, required: An English Wikipedia article or draft, by title (`Draft:Dominic McLaughlin`) or address (`https://en.wikipedia.org/wiki/…`).
      - `let_wikidata_manage` boolean: For a draft only: `false` keeps the description site-authored. By default a draft’s credit hands the description to the Wikidata sync, which leaves it alone until the draft is an article linked from the entry’s Wikidata item.
    - `short` string, nullable: The short name (`/<short>`); `null` removes it.
    - `image_id` string, nullable: The lead image, by media id; `null` removes it.
    - `gallery` string[]: The whole gallery after the lead, in order, by media id: it replaces the one there.
    - `image_links` object: The whole map of links on the entry’s images, media id → absolute http(s) address. Needs the `link_images` capability.
    - `custom_handle_order` boolean: Keep `handles` in the order given, rather than the site’s order.
    - `handles` object[]: The whole list of handles, in order: it replaces the one there. Not with `add_handles` / `remove_handles`.
      - `platform_id` string, required
      - `value` string, required
      - `display` string, nullable: A label to show instead of the value.
    - `add_handles` object[]: Handles to put on the entry, at the end of its list as it is when the change is applied (a proposal: when it is approved). One the entry has already (the same value, in any case the platform folds) changes nothing. No base revision is needed for it. Not with `handles` (400 `handles_with_ops`).
      - `platform_id` string, required
      - `value` string, required: Not blank. A website is completed to an address, as in `handles`.
      - `display` string, nullable: A label to show instead of the value.
    - `remove_handles` object[]: Handles to take off, by value — or, for an email the caller may not see, by `ref` (an address is refused: `masked_handle_needs_ref`). One the entry does not have changes nothing. A value the Wikidata sync supplied is held back from it, as when a list leaves it out. Not with `handles`.
      - `platform_id` string, required: The platform’s id.
      - `value` string: The handle, as stored or in any case the platform folds.
      - `ref` string: Instead of `value`, for an email the caller may not see: the `ref` `GET /api/editor/{vhid}` gives it.
    - `relinquish` string[]: Fields to hand back to the Wikidata sync.
    - `takeover` string[]: Fields to take from the Wikidata sync, keeping their value.
    - `handle_takeover` object[]: Handles to take from the Wikidata sync.
      - `platform_id` string, required: The platform’s id.
      - `value` string, required: The handle as stored.
    - `handle_relinquish` object[]: Handles to hand to the Wikidata sync, while Wikidata lists them.
      - `platform_id` string, required: The platform’s id.
      - `value` string, required: The handle as stored.
    - `handle_release` object[]: Values held back from the sync that it may add again.
      - `platform_id` string, required: The platform’s id.
      - `value` string, required: The handle as stored.
  - `qid` string, nullable: Its Wikidata item, `Q<n>`. One that is sent must be a real QID.

## Response `200`

Queued; or with `?check=1`, it would be (nothing is queued).

- union
  - ProposalQueued: The proposal is queued for a reviewer. Sending the same proposal again while it waits answers the same id rather than queuing it twice.
    - `ok` true, required
    - `submissionId` string, required: The proposal’s id.
    - `status` 'pending', required: It waits for a reviewer.
  - object
    - `ok` true, required
    - `check` true, required

## Other responses

- `400`: The proposal is malformed: no title (`title_required`), a bad QID (`bad_qid`), an image (`image_on_new_entry`), a Wikipedia credit (`credit_on_new_entry`: name it once the entry exists), a handle on a platform the catalog does not have or has disabled (`invalid_platform`, naming it), a field of the wrong type, or a `check` that is not `1` (`bad_check`). Or the request sent a key and a session cookie together (`bearer_with_cookie`): send one. Or the Idempotency-Key is not 1–255 printable ASCII characters (`bad_idempotency_key`).
- `401`: No key was sent (`auth_required`), or the key was refused: unknown, revoked or expired, its holder may no longer use keys, or this instance takes none. Carries `WWW-Authenticate: Bearer`. After 60 refused keys from one IP address in a minute, every key from there is answered `429` (text, with `Retry-After`) until the minute is up.
- `403`: The account may not propose (`forbidden`). A read-only key tried to change something (`read_only_key`), or the account is blocked (`forbidden`).
- `409`: An entry is already on that Wikidata item (perhaps a deleted one): it is named (`already_exists`). Or Wikidata has merged the item into another (`qid_merged`): `wikidata_item` names the item it kept, and nothing is queued. Or the short is the address of a site redirect (`short_is_redirect`): choose another, or an administrator deletes the redirect first. Or the first request with this Idempotency-Key is still running (`idempotency_key_in_progress`): try again after `Retry-After` seconds.
- `413`: The body is over 512 KiB.
- `422`: This Idempotency-Key was used for a different request in the last 24 hours (`idempotency_key_reused`): nothing was written.
- `429`: Too many changes in the last minute: counted per IP address, per account and per key (an admin key’s per key alone, at the limit set on Console → Rate limits). Wait the number of seconds `Retry-After` gives.
- `503`: New entries are paused (`not_accepting`, JSON), or the site is down for maintenance (an HTML page). Try again later.

---

[API](https://skmtc.dev/verifiedhandles/apis/verified-handles-api.md) · [All operations](https://skmtc.dev/verifiedhandles/apis/verified-handles-api/llms.txt) · [OpenAPI document](https://skmtc.dev/verifiedhandles/apis/verified-handles-api/revisions/40720de2e0ec?raw)
