Skip to content

Website import

POST /storefront/import copies the WordPress website behind a connected WooCommerce shop into the business’s Bottle Shop, as drafts, in the background. GET /storefront/import says how it is going. The office’s Copy your WooCommerce website card uses both.

POST /storefront/import
Content-Type: application/json
{ "shopId": "0192…", "replaceDraft": true }
Field What it is
shopId A connected WooCommerce shop (GET /shops). A Shopify shop is 409.
replaceDraft Must be true when the shop has been published, has pages or posts, or its draft has changed (replacesWork in the GET). Otherwise 409 replace_needed.

It answers 202 at once with the same shape as the GET. Only one runs at a time for a business: 409 while one is queued or running. At most five runs a business starts in a day; a sixth is 429 (rate_limited). Starting again after one failed, for the same shop, carries on the same run and does not count as another. If the job cannot be queued, the run is marked failed (notStarted) and the answer is 503.

GET /storefront/import answers { import, replacesWork }, where import is the latest run or null:

  • status: queued, running, done, failed or undone. A run, queued or running, that has said nothing for ten minutes reads as failed with error stopped, and starting again carries it on.
  • step: fetching, pictures, converting, drafting, done, and progress { done, total } within it.
  • counts: pages, posts, menus, pictures and pictures that failed.
  • draftedByAi: whether a model proposed the draft, or Bottle’s rules did.
  • notes: message keys and values (siteImport.notes.* in the catalogue).
  • error: a key in siteImport.errors when it failed.

The office also hears /storefront/import on the live stream as it moves.

POST /storefront/import/{id}/undo puts the pages and posts the run made in the bin, but only those whose version is the one the run recorded when it made or last laid them out; anything changed or published since stays and is counted in kept. It puts the shop’s draft back as it was only when the run saved one, and only while the draft is still the version the run saved, in the same statement; otherwise the draft stays and draftKept is true. The run is marked undone.

Starting needs a person signed in as an owner or admin, holding both shops:write (the run uses the shop connection, which keys and assistants may never hold) and storefront:write. It is counted against the smaller allowance for expensive requests. Reading needs storefront:read; undoing needs a person signed in with storefront:write. No new scope.

Only public WordPress content, through the WordPress REST API on the shop’s own address (/wp-json/, or ?rest_route= on sites without pretty permalinks): published pages and posts, their featured pictures, authors’ display names, categories and tags, the site’s name, tagline, logo and icon, and the colours its home page declares. No credentials are sent: the WooCommerce key only opens WooCommerce’s own routes and stays there. Menus are read from /wp/v2/menus or the WP REST API Menus plugin when the site allows; newer WordPress keeps them private, so they are rebuilt from the page tree, and the run says so.

The website must be publicly accessible over HTTPS. An import includes up to 60 pages and the newest 100 posts.

Pictures on the site’s own host (with or without www) are copied first; pictures the pages showed from other hosts come after, count against the same cap, and are named in a note. An import includes up to 80 pictures, with a limit of 8 MB per picture. Unavailable or unsupported pictures are reported.

Gutenberg comments go; shortcodes that wrap words keep the words, standing ones go, [[escaped]] ones are written out, and galleries become their pictures. Embeds are counted and left out. Pictures point at their copies in Bottle, or go. Links to the old site point at the new page or post where there is one, and at the shop’s own pages for WooCommerce’s shop, basket, checkout, account and categories. Then the HTML goes through the same content checks as other shop pages. A page too long once cleaned is cut at a tag.

When the model lays a page out differently, the page is changed only while its version is still the one the run recorded when it made it, checked with the page held; a page the owner changed meanwhile is left as they have it.

Pages are split at their second-level headings into text, text and picture, and picture sections, with widths. A slug already taken by a page or post gets -2, -3 and so on; an old slug that had to change becomes a redirect where nothing else holds it.

The import creates a draft, not a published website. draftedByAi tells you whether AI helped arrange it. Review the pages, pictures, menus and links in the shop preview before publishing.

Changes made while an import runs are kept rather than overwritten. Check the reported notes and counts when it finishes. Undo also keeps pages or drafts that have changed since the import.

An address something in the Bin holds, its own or an old one that sends shoppers to it, counts as taken.