# Dotb Public API > Prepare Vinted listings for import: create pending items and upload their photos, then > import them into Vinted through the Dotb browser extension. Also access Vinted orders for > shipping and accounting, and look up Vinted reference data (catalogs, brands, colors, > sizes, video game ratings) and connected Vinted accounts. Requires a Boutique AI plan. - Base URL: https://dotb.io - Auth: Bearer token (`dotb_pk_...`) in the `Authorization` header. Requires a Boutique AI plan. - OpenAPI spec: /api/public/v1/openapi.json - Interactive docs: /api/public/v1/docs Errors share one shape: `{"error": {"type", "message", "details", "request_id"}}`. Common statuses: 401 (missing/invalid token), 402 (no Boutique AI subscription), 404 (not found or not owned), 422 (validation error). Rate limits apply per API token (not per user) — each token gets its own allowance of 60 requests/minute and 10,000 requests/day. Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers; exceeding a limit returns 429 with a `Retry-After` header (seconds). ### Accounts ## GET /api/public/v1/accounts — List Vinted accounts Returns the Vinted accounts connected to the authenticated user. **Response 200:** List of accounts. Fields: `data` (array) — `id` (uuid), `login` (string), `vinted_id` (integer), `country` (string, nullable). ### Catalogs ## GET /api/public/v1/catalogs — List catalogs Returns the Vinted catalog tree up to a given depth for the resolved country. Responses are publicly cacheable for 1 hour. **Query parameters:** - `country` (string, optional) — ISO 3166-1 alpha-2 country code (e.g. "FR"), 2 chars. Inferred from account when omitted. - `depth` (integer, optional) — Maximum tree depth to return (0–6, default 2). **Response 200:** List of catalogs. Fields: `data` (array) — `id` (integer), `title` (string), `parent_id` (integer, nullable), `depth` (integer). ## GET /api/public/v1/catalogs/{catalog_id} — Get catalog Returns a single catalog by its Vinted id along with its ancestor breadcrumb. **Query parameters:** - `catalog_id` (integer, required, path) — Vinted catalog id. - `country` (string, optional) — ISO 3166-1 alpha-2 country code. Inferred from account when omitted. **Response 200:** Catalog with ancestors. Fields: `catalog` (object: `id`, `title`, `parent_id` nullable, `depth`), `ancestors` (array of `id`, `title`). ## GET /api/public/v1/catalogs/{catalog_id}/options — Get catalog form options Returns the available conditions, package sizes, size groups, and attributes for a catalog — i.e. everything needed to render a listing form. **Query parameters:** - `catalog_id` (integer, required, path) — Vinted catalog id. - `country` (string, optional) — ISO 3166-1 alpha-2 country code. Inferred from account when omitted. - `locale` (string, optional) — BCP 47 locale code for translated titles. Defaults to the country's language. **Response 200:** Catalog options. Fields: `catalog` (object), `ancestors` (array of `id`, `title`), `conditions` (array — `id`, `title`, `explanation`), `package_sizes` (array — `id`, `title`, `description`, `standard` boolean), `size_groups` (array — `id`, `title`, `sizes`: array of `id`/`title`), `attributes` (array — `code`, `title`, `required` boolean, `selection_type` nullable, `selection_limit` nullable, `display_type` nullable, `options`: array of `id`/`title`). ### Brands ## GET /api/public/v1/brands — Search brands Full-text search over Vinted brands. The `q` query parameter is required. **Query parameters:** - `q` (string, required) — Search query (required, non-empty). - `limit` (integer, optional) — Maximum number of results (1–100, default 25). **Response 200:** Brand search results. Fields: `data` (array — `id` integer, `title` string), `has_more` (boolean), `next_cursor` (string, nullable). ### Colors ## GET /api/public/v1/colors — List colors Returns all Vinted colors. Titles are localized to the language of the given `country` (defaults to English). Responses are publicly cacheable for 1 hour. **Query parameters:** - `country` (string, optional) — ISO 3166-1 alpha-2 country code (e.g. "FR") used to localize titles. Defaults to English when omitted or unknown. **Response 200:** List of colors. Fields: `data` (array) — `id` (integer), `title` (string), `hex` (string, nullable), `code` (string, nullable). ### Video game ratings ## GET /api/public/v1/video-game-ratings — List video game ratings Returns all Vinted video game ratings (e.g. PEGI 3, PEGI 7). Titles are localized to the language of the given `country` (defaults to English). Responses are publicly cacheable for 1 hour. **Query parameters:** - `country` (string, optional) — ISO 3166-1 alpha-2 country code (e.g. "FR") used to localize titles. Defaults to English when omitted or unknown. **Response 200:** List of video game ratings. Fields: `data` (array) — `id` (integer), `title` (string). ### Items Item object fields (shared by list/get/create/update responses): `id` (uuid), `vinted_account_id` (uuid), `vinted_id` (integer, nullable — set once imported to Vinted), `status` (string — e.g. `pending`, `imported`), `title` (string, nullable), `description` (string, nullable), `price` (decimal string, nullable), `currency` (string, nullable), `catalog_id` (integer, nullable), `brand_id` (integer, nullable), `brand` (string, nullable), `size_id` (integer, nullable), `status_id` (integer, nullable — Vinted condition id), `color_ids` (array of integer), `package_size_id` (integer, nullable), `video_game_rating_id` (integer, nullable), `isbn` (string, nullable), `manufacturer` (string, nullable), `manufacturer_labelling` (string, nullable), `is_unisex` (boolean, nullable), `disposal_conditions` (boolean), `measurement_length` (integer, nullable), `measurement_width` (integer, nullable), `item_attributes` (array of object), `photos` (array — `image_no` integer, `url` string nullable), `sku` (string, nullable), `location` (string, nullable), `purchase_price` (decimal string, nullable), `minimum_offer_price` (decimal string, nullable), `counter_offer_price` (decimal string, nullable), `accept_offers_enabled` (boolean), `messages_enabled` (boolean), `restock_enabled` (boolean, nullable), `restock_quantity` (integer, nullable), `supplier_link` (string, nullable). ## GET /api/public/v1/items — List items Returns the authenticated user's Vinted items with keyset pagination. **Query parameters:** - `status` (string, optional, enum: `pending`, `imported`, `all`) — Filter by import status: pending (default), imported, or all. - `account_id` (uuid, optional) — Restrict results to a specific Vinted account UUID. - `limit` (integer, optional) — Page size (1–100, default 25). - `cursor` (string, optional) — Opaque keyset cursor from a previous response's `next_cursor`. **Response 200:** Paginated list of items. Fields: `data` (array of item objects, see above), `has_more` (boolean), `next_cursor` (string, nullable). ## POST /api/public/v1/items — Create item Creates a pending (source: dotb) item for the authenticated user. Photos are not part of this request; upload them afterwards via POST /items/:id/photos. **Request body:** (JSON) - `vinted_account_id` (uuid, required) — UUID of the Vinted account on Dotb to associate the item with. - `title` (string, required) — Item title (5–100 chars, max 6 non-title-case capital letters). - `description` (string, required) — Item description (5–2000 chars). - `price` (decimal string, required) — Listing price, e.g. `"29.90"`. - `currency` (string, required) — ISO 4217 currency code, e.g. `"EUR"`. - `catalog_id` (integer, required) — Vinted catalog (category) id. - `brand_id` (integer, optional) — Existing Vinted brand id (look it up via GET /brands). Takes priority over `brand` — the canonical name is resolved and returned automatically. To create an item with no brand, pass the special `brand_id` 1 ("no_brand"). - `brand` (string, optional) — Brand name for a new/custom brand; for an existing brand pass brand_id which the API resolves to the name. - `color_ids` (array of integer, optional) — Up to 2 Vinted color ids. - `size_id` (integer, optional) — Vinted size id. - `status_id` (integer, optional) — Vinted condition id. - `package_size_id` (integer, optional) — Vinted package size id. - `video_game_rating_id` (integer, optional) — Vinted video game rating id (see /video-game-ratings). - `isbn` (string, optional) — ISBN (books/media). - `manufacturer` (string, optional) — Manufacturer. - `manufacturer_labelling` (string, optional) — Manufacturer labelling info. - `is_unisex` (boolean, optional) — Unisex flag. - `disposal_conditions` (boolean, optional) — Disposal conditions acknowledgement. - `measurement_length` (integer, optional) — Length (cm). - `measurement_width` (integer, optional) — Width (cm). - `item_attributes` (array of object, optional) — Catalog-specific attribute selections. - `vinted_account_id`, plus Dotb-only inventory/automation fields (not sent to Vinted): `sku` (string, optional), `location` (string, optional), `purchase_price` (decimal string, optional — your cost price, not shown to buyers), `minimum_offer_price` (decimal string, optional), `counter_offer_price` (decimal string, optional), `accept_offers_enabled` (boolean, optional — allow buyers to make offers), `messages_enabled` (boolean, optional — allow buyers to send messages), `supplier_link` (string, optional — item source URL, https:// is prepended when no scheme is given), `restock_enabled` (boolean, optional — enable auto-restock), `restock_quantity` (integer, optional — -1 = unlimited, range -1..32767). **Response 200:** Created item (same item object shape as List items). ## GET /api/public/v1/items/{id} — Get item Returns a single item by id. Returns 404 if the item belongs to another user. **Query parameters:** - `id` (uuid, required, path) — Item UUID. **Response 200:** Item (same item object shape as List items). ## PATCH /api/public/v1/items/{id} — Update item Updates a pending (dotb-created) item. Only items without a vinted_id are editable; imported items return 404. Merges data fields. Photos are managed separately via POST /items/:id/photos. **Query parameters:** - `id` (uuid, required, path) — Item UUID. **Request body:** (JSON) Same fields as Create item, all optional — merges into the existing item. **Response 200:** Updated item (same item object shape as List items). ## POST /api/public/v1/items/{id}/photos — Upload an item photo Uploads a single image file (multipart/form-data, field `file`) and appends it to a pending item's photos. Call it once per photo. Only items without a vinted_id are editable; imported items return 404. Max file size is ~8MB (Plug.Parsers default). **Query parameters:** - `id` (uuid, required, path) — Item UUID. **Request body:** (multipart/form-data) - `file` (file, required) — The image file (jpeg/png/webp). **Response 200:** Updated item (same item object shape as List items) including the new entry in `photos`. ### Orders Order object fields (shared by list/get responses): `id` (uuid), `title` (string, nullable), `status` (string, nullable — raw Vinted status), `normalized_status` (string, nullable — see the `status` filter enum on List orders), `status_updated_at` (ISO8601 datetime, nullable), `order_date` (ISO8601 datetime, nullable), `shipping_deadline_date` (ISO8601 datetime, nullable), `ready_for_pickup_at` (ISO8601 datetime, nullable), `currency` (string, nullable), `original_price` (decimal string, nullable), `subtotal` (decimal string, nullable), `subtotal_vat` (decimal string, nullable), `shipping` (decimal string, nullable), `shipping_vat` (decimal string, nullable), `service_fee` (decimal string, nullable), `vat_rate` (decimal string, nullable), `payout` (decimal string, nullable), `gross_profit` (decimal string, nullable), `total_cost` (decimal string, nullable), `item_count` (integer), `invoice_id` (string, nullable), `note` (string, nullable), `carrier_name` (string, nullable), `tracking_code` (string, nullable), `tracking_url` (string, nullable), `transaction_user_status` (string, nullable), `vinted_transaction_id` (integer, nullable). Always-present base fields (not include-gated): - `shipping_address` (object) — `name`, `line1`, `line2`, `city`, `postal_code`, `country_code` (all string, nullable). - `shipping_label_url` (string, nullable) — null until the shipping label has been fetched. Optional blocks, expanded via the `include` query parameter (`items`, `buyer`, `account`): - `account` (object) — `id` (uuid), `login` (string, nullable), `vinted_id` (integer, nullable), `country_code` (string, nullable), `has_company` (boolean). - `buyer` (object, nullable) — `login` (string, nullable), `name` (string, nullable), `email` (string, nullable), `vinted_id` (integer, nullable), `country_code` (string, nullable). - `items` (array) — `id` (uuid — use it to PATCH the item), `vinted_item_id` (string, nullable), `vinted_id` (integer, nullable), `title` (string, nullable), `catalog_id` (integer, nullable), `sku` (string, nullable), `location` (string, nullable), `thumbnail_url` (string, nullable), `supplier_link` (string, nullable), `original_price` (decimal string, nullable), `selling_price` (decimal string, nullable), `purchase_price` (decimal string, nullable). ## GET /api/public/v1/orders — List orders Returns the authenticated user's Vinted orders with keyset pagination. **Query parameters:** - `status` (string, optional, enum: `payment_received`, `label_ordering`, `label_failed`, `label_sent`, `packed`, `shipped`, `ready_for_pickup`, `delivered`, `completed`, `returning`, `suspended`, `cancelled`) — Filter by normalized_status. Invalid values are ignored. - `account_id` (uuid, optional) — Restrict results to a specific Vinted account UUID. - `from` (string, optional) — Inclusive lower bound on order_date. Accepts a date (`YYYY-MM-DD`) or full ISO8601 timestamp; a date-only value covers the whole day (from 00:00:00 UTC). Invalid values are ignored. - `to` (string, optional) — Inclusive upper bound on order_date. Accepts a date (`YYYY-MM-DD`) or full ISO8601 timestamp; a date-only value covers the whole day (through 23:59:59 UTC). Invalid values are ignored. - `limit` (integer, optional) — Page size (1–100, default 25). - `cursor` (string, optional) — Opaque keyset cursor from a previous response's `next_cursor`. A cursor is bound to the `sort` it was created with — changing `sort` mid-pagination invalidates it, so restart from the first page (no cursor) whenever you change `sort`. - `include` (string, optional) — Comma-separated list of optional blocks to expand: `items`, `buyer`, `account`. Unknown tokens are ignored. Absent by default (lean response). `shipping_address` and `shipping_label_url` are always-present base fields (not include-gated). - `sort` (string, optional, enum: `order_date`, `shipping_deadline_date`) — Sort column, fixed direction per column. `order_date` (default) — newest first. `shipping_deadline_date` — soonest deadline first; orders without a deadline sorted last. Invalid/empty values fall back to `order_date`. **Response 200:** Paginated list of orders. Fields: `data` (array of order objects, see above), `has_more` (boolean), `next_cursor` (string, nullable). ## GET /api/public/v1/orders/{id} — Get order Returns a single order by id. Returns 404 if the order belongs to another user. **Query parameters:** - `id` (uuid, required, path) — Order UUID. - `include` (string, optional) — Comma-separated list of optional blocks to expand: `items`, `buyer`, `account`. Unknown tokens are ignored. Absent by default (lean response). `shipping_address` and `shipping_label_url` are always-present base fields (not include-gated). **Response 200:** Order (same order object shape as List orders). ## POST /api/public/v1/orders/{id}/pack — Mark order as packed Marks an order as packed (a Dotb fulfillment status between label_sent and shipped). Only orders currently in `label_sent` can be packed; any other status returns 409. This is a local status change only — nothing is pushed to Vinted. **Query parameters:** - `id` (uuid, required, path) — Order UUID. **Response 200:** Updated order (same order object shape as List orders), with `normalized_status` set to `packed`. **409** if the order is not currently in `label_sent`. ## PATCH /api/public/v1/orders/{order_id}/items/{id} — Update an order item Updates the inventory fields of an item within an order — the same fields editable in the dashboard. Only the fields you send are changed; setting `purchase_price` recalculates the order's profit totals. Returns 404 if the order or item is not found or belongs to another user. Requires the `orders_write` scope. **Query parameters:** - `order_id` (uuid, required, path) — Order UUID. - `id` (uuid, required, path) — Order item UUID (the `id` field of an order's `items` entry). **Request body:** (JSON) All fields optional; only sent fields are changed. - `sku` (string, nullable) — Seller SKU for inventory. - `location` (string, nullable) — Storage location. - `supplier_link` (string, nullable) — Source URL; `https://` is prepended when no scheme is given. - `purchase_price` (decimal string, nullable) — Your cost price; recalculates order profit totals. **Response 200:** The updated order item (same shape as an order's `items` entry).