Files
SlabUploader/docs/contracts/WOO-API.md
Ty 120e0be871 docs(m3): settle deterministic title and Call 2 design
Encode the recovered per-leaf title/short-description rule and the Call 2
input set into the point of record.

- REQUIREMENTS.md: METADATA-55 now produces the description only; METADATA-60
  carries the ruled input set; METADATA-80 is the deterministic title; new
  METADATA-81 is the deterministic spec-line short description; METADATA-85
  selects the patterns; REVIEW-15 declares the primary before Call 2;
  PUBLISH-55 carries an explicit name+SKU slug.
- CONTENT-WOO.md: per-leaf title and short-description catalog, slot order,
  dimension placement, and the Cook Woods provenance.
- PROMPTS.md: Call 2 inputs and output; the deterministic patterns are cited,
  not restated.
- CREATE.md, WOO-API.md, MILESTONES.md, task_breakdown.md updated to match.

Modeled on Cook Woods product-title form; the seven per-leaf prose templates
and Specialty cuts are parked in the M3 breakdown.
2026-09-19 11:36:03 -07:00

6.1 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
slug (name + SKU) slug string sanitized; WordPress dedupes on collision
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
slug wp_posts.post_name (varchar(200)) 200 200 WordPress wp_unique_post_slug truncates the base near 200

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.