Create and update items
POST /api/v2/items creates a physical catalogue item. PATCH /api/v2/items/{id} updates supplied fields. Neither creates a lot, publishes an auction, changes bidding, or uploads images. Existing lots that use the item retain their history and receive the normal item-change invalidation.
Both endpoints require lots.write and lots.read. Attaching an existing seller also requires seller_profiles.read; attaching categories requires categories.read. Maker and delivery-class references use the already-required lots.read permission. Use a server-held API key, never a key embedded in storefront JavaScript.
Create
curl https://app.bidvise.com/api/v2/items \
-H "Authorization: Bearer $BIDVISE_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"external_reference":"2026_9-1000","title":"Zilveren kan","translations":{"en":{"title":"Silver jug"}},"estimate":{"low":{"amount":10000,"currency":"EUR"},"high":{"amount":20000,"currency":"EUR"}}}'
A successful create returns 201, { "data": { ...item... } } and a Location API path. A successful PATCH returns 200 with the same item representation. ?expand=images is supported; list filters and pagination parameters are not.
Supply a nonblank external_reference and a title in the house’s default language, either as title or under translations.<locale>.title. Flat fields and a supplied default-locale translation must agree. Supported locales: nl, en, fr, de, es, zh, it, pl, hu.
Partial updates
Only supplied fields change. Text fields are title, description, condition, dimensions and weight; the same names apply inside each translation. Returned translations contains actual stored rows, without fallback copies. Flat fields retain the existing house-default text caches.
- Omit a field to preserve it, including fields inside a supplied translation.
- Null clears nullable text,
seller,consignment,delivery_class, or the entireestimate. The default-language title andexternal_referencecannot be cleared. categories: []clears categories. Otherwise send existing same-housecat_…IDs;sellertakes an active same-housesel_…ID. Bare UUIDs are accepted too; canonical duplicate categories are rejected.makersreplaces the ordered maker list. Send same-housemkr_…IDs (or bare UUIDs) in the intended order;[]clears it. Inactive makers are also accepted. Canonical duplicates andnullare rejected.delivery_classtakes one same-housedlc_…ID or bare UUID;nullclears it. Look up both kinds through the reference lists.- Either estimate bound can be changed or cleared individually. The resulting low cannot exceed high. Amounts must match the house currency and be nonnegative integer minor units, in multiples of 100, at most 214748364700. Estimates currently store whole currency units; fractional values are rejected rather than truncated.
Unknown fields, wrong JSON types, NUL bytes, unknown locales and unavailable references are explicit errors. Seller and consignment must remain consistent; see the assignment rules below.
Failure and retry
Validation returns 422 Problem Details, optionally with errors: [{ "field": "estimate.low.amount", "code": "invalid", "message": "…" }]. Invalid JSON or unsupported query parameters return 400. Missing permissions return 403. A foreign or unknown target item returns 404. No part of a failed transaction is committed.
An external reference is unique within the house, including archived items. Duplicate POST or conflicting PATCH returns 409, never an implicit update. After a timeout or 409, GET /items?external_reference=..., follow pagination, compare the returned item with the intended row, and deliberately PATCH only if needed. If no active match exists, the reference may be reserved by an archived item; contact support rather than inventing another reference.
There is no general Idempotency-Key contract yet. Concurrent PATCH requests lock the item and apply serially; for overlapping fields the last writer wins. Coordinate import writers when overwriting existing catalogue text. Creating lots and other import operations are not part of the API yet. The image endpoints are described below.
External references accept at most 1024 UTF-8 bytes (a character may use more than one byte). Category-only, maker-only (including reordering) and translation-only changes also advance updated_at. Repeating an identical maker order and delivery class preserves timestamps and linked-lot caches. Maker joins retained in the list keep their identity; removed links are deleted, without changing the makers themselves. Duplicate legacy translation rows return a typed 500 problem; a failed write rolls back completely. Contact support to repair the existing data before retrying.
Assign an existing consignment
Send consignment: "con_…" alongside other item fields. This needs seller_profiles.read in addition to the item read/write permissions. Resolve the actual ID through consignment reads. The assignment uses the existing backoffice seller, locking and commission-inheritance rules; it does not edit the consignment’s terms.
- Omit
consignmentto preserve it. Send null to clear it, preserving the seller unlessselleris also supplied. - An item with no seller inherits the consignment seller when
selleris omitted. An existing seller must match; the API will not silently switch owners. - To move between sellers and consignments, send the matching
sellerandconsignmenttogether. Explicitseller: nullwhile retaining a consignment is rejected. - New assignments into a locked consignment return 422. Existing items can still be edited, or detached, under the existing backoffice rules. Repeating an unchanged assignment preserves the item timestamp.
- References must be active records in the same house. Invalid references or a later error roll back the entire item write, including translations and other relationships. A target consignment is locked for the database transaction so concurrent staff locking cannot slip between checking it and saving the assignment.
The response adds the consignment ID or null. It never includes private notes or commission details. No consignment records are created by an item request.
Image processing status
Managed image reads (GET /items/{item}/images and the image detail) include processing_failure: null, or an object with code: "derivative_processing_failed" and an at timestamp. It records a failed processing attempt. An automatic retry may still be running, and a successful retry or a replaced source clears it. A null value does not prove that older images were processed. Public gallery responses do not include this field.
Regenerate derivatives from an existing source
POST /items/{item}/images/{id}/reprocess with Content-Type: application/json and the body {} asks Bidvise to regenerate the image’s derivatives from its existing source. It requires lots.write and lots.read. The response is 202 with the image and processing: true. The source, the image ID and its gallery visibility and position do not change, so a private image stays private.
If the image is already processing, the response is 409 and nothing new is scheduled. After a timeout or a 503, read the image again before retrying: there is no idempotency key for this command. Unsupported fields return 422.
Delete a stored image
DELETE /items/{item}/images/{id} with no body removes an image. It requires lots.read and lots.write. Success is 204 with no body; an unknown or already deleted image returns 404. Private images and images that are still processing can be deleted.
Deleting the featured image does not choose a new one. Use gallery replacement to set a new featured image. The other images keep their visibility and order, and the item and its lots are kept.
Stored files are removed after the deletion is committed. A 503 does not tell you whether that clean-up finished, so read the gallery back before retrying. A lock conflict returns 409; read the gallery before retrying.