Files
SlabUploader/docs/contracts/WOO-API.md
T
Ty 01aa4c52c3 docs(phase2): reconcile requirements and migrate capabilities/contracts
Surface-matrix sweep of every source doc; added nine missed behaviors (METADATA-115, REVIEW-50, APP-55/60/65, SETTINGS-45 mode, Generate-text availability, defaults-off). 153 requirements, 0 coverage gaps.

Migrated capabilities to docs/capabilities/ and contracts to docs/contracts/; added WOO-API, API, DATA-MODEL, PROMPTS, UX, TEST-SPEC. Populated MILESTONES; branch-neutral trunk docs; renamed umbrella term to Woo Slab Taxonomy. Archived reconciliation working records under .audit/archive/.
2026-09-18 21:02:06 -07:00

5.9 KiB

WooCommerce API contract

Status: SPEC · 2026-09-18 · external dependency: WooCommerce REST API v3. Source: official WooCommerce REST API v3 documentation (https://woocommerce.github.io/woocommerce-rest-api-docs/).

This contract pins the exact WooCommerce surface the app codes against. docs/contracts/CONTENT-WOO.md owns the listing copy and payload intent; this file owns the wire shape and the external constraints.

Requirements impact

Requirement Impact on this design
SETTINGS-5, SETTINGS-10, SETTINGS-15 base URL, HTTPS, app-password auth
SETTINGS-35, SETTINGS-50, SETTINGS-51, SETTINGS-65 pricing, taxonomy sync, tag scope, create status
METADATA-5, METADATA-10, METADATA-15, METADATA-30 categories, attributes, tags shapes
REVIEW-10, REVIEW-25, REVIEW-45, REVIEW-50 name, price, SKU, field limits
PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-20, PUBLISH-25, PUBLISH-30, PUBLISH-35 create sequence, draft rule, errors
PUBLISH-40, PUBLISH-45, PUBLISH-55, PUBLISH-60 images, payload fields, sold-individually
APP-35, APP-50 error envelope mapping

1. Transport and auth

  • Base path: ${WOO_BASE_URL}/wp-json/wc/v3.
  • WOO_BASE_URL is HTTPS only and injected from env.
  • Auth: WordPress application password over HTTP Basic. The consumer-key example in the Woo docs is not used.
  • Content type application/json. Dates ISO8601 (YYYY-MM-DDTHH:MM:SS). Monetary values are strings with two decimals.

2. Endpoints used

Purpose Method and path
Sync categories GET /products/categories?per_page=100&page=N
Sync tags GET /products/tags?per_page=100&page=N
Sync attributes GET /products/attributes?per_page=100
Sync attribute terms GET /products/attributes/{id}/terms?per_page=100
SKU lookup GET /products?sku={sku}
Create product POST /products
Upload media POST /wp-json/wp/v2/media (WordPress core)

3. Product create field alignment

Our value Woo field Woo type Enum / constraint
title name string none documented
— type string simple (default)
create status status string draft, pending, private, publish; default publish
sku sku string unique; no documented format
price regular_price string monetary string, 2 decimals
description description string none documented
short_description short_description string none documented
species + wood categories categories array of {id: integer} leaf ids
fig-* / feat-* tags tags array of {id: integer} tag ids
uploaded PNGs images array of {id: integer} attachment ids, lineup order
five locked attributes attributes array of attribute elements see §4
— virtual boolean default false
— downloadable boolean default false
— catalog_visibility string visible, catalog, search, hidden; default visible
— sold_individually boolean default false; set true

sold_individually: true is the Woo mechanism that enforces "one slab is one unit."

4. attributes element shape

Global attributes are referenced by id (synced from Woo), never created by name. Each element:

{
  "id": 8,
  "position": 0,
  "visible": true,
  "variation": false,
  "options": ["Live Edge"]
}
Attribute options
Edge Type [term name]
Figure [term name, ...]
Grade [term name]
Thickness [term name]
Moisture [term name]

options carries term names, not ids. visible is true; variation is false.

5. Categories, tags, images shapes

  • categories: [{"id": 9}, {"id": 14}]
  • tags: [{"id": 34}]
  • images: [{"id": 42}, {"id": 793}], in photos-ready lineup order.
  • Media upload: POST /wp-json/wp/v2/media as multipart/form-data with the PNG bytes; the response id is the attachment id used in images. Keep alpha; PNG only.

6. Error shape

{ "code": "woocommerce_rest_term_invalid", "message": "Resource doesn't exist.", "data": { "status": 404 } }

401 auth, 400 bad request, 404 missing, 500 server. These map into the app's uniform envelope and never reach the owner raw.

7. Pagination

per_page max 100, page 1-based. Read X-WP-Total and X-WP-TotalPages; follow pages until exhausted. Taxonomy lists return in full to the client.

8. No documented maximum lengths

The Woo v3 docs state no maximum length for name, description, short_description, sku, or regular_price. Do not invent caps. The app enforces non-empty required fields and its own local formats.

9. Field length limits

Hard limits are verified from WordPress/WooCommerce source; the display caps are conventions (Google states no numeric limit).

Field Storage Hard limit Recommended display cap Rationale
name wp_posts.post_title (text) 65,535 60 on-screen title-tag width
short_description wp_posts.post_excerpt (text) 65,535 160 search snippet / meta description width
description wp_posts.post_content (longtext) ~16.7M none no word-count target; write for the page
sku wc_product_meta_lookup.sku (varchar(100), index sku(50)) 100 50 index prefix length

Sources: WordPress schema.php, WooCommerce class-wc-install.php, class-wc-product-data-store-cpt.php, and Google Search Central (title links, snippets, SEO starter guide).

10. Media size

The store exposes its upload cap read-only as max_upload_size on system status. Validate the processed PNG against it before upload and surface a plain, actionable error if exceeded.

11. Versioning

Woo wc/v3 requires WooCommerce 3.5+ and WordPress 4.4+ with pretty permalinks. Breaking Woo API changes are handled by the app's own /api/v1 version, not by pinning the store.