Skip to content
Sign in

Documentation

The browser explains and previews; the product CLI and the REST API perform repeatable work. Every page on product.cloud shows the equivalent command and route for what you are looking at.

CLI

Install
brew install product-cloud/tap/product
# or
cargo install product-cli

Sign in with the browser (OAuth 2.0 Authorization Code with PKCE) or, on headless machines, with the device authorization flow. Refresh tokens are kept in the operating system keychain; commands never embed credentials.

Authenticate
product auth login
product auth login --device
product auth status
Consume a pinned revision
product clone acme/power-tools-eu --revision 2026.09
product pull acme/power-tools-eu@2026.09 --include products,attributes --market DE
product diff 2026.08..2026.09 --entity product
product query products --where 'brand = "ACME"' --select gtin,mpn,name
Synchronize (plan first, then apply with a checkpoint)
product sync plan acme/power-tools-eu --target ./mirror
product sync run acme/power-tools-eu --target ./mirror \
  --checkpoint .product/checkpoints/mirror.json --resume

REST API

The normative API is REST described by OpenAPI 3.1 at https://api.product.cloud/v1. The web platform uses exactly these routes. Any read can be pinned with ?revision= (branch, release tag, or commit digest).

Route families
RoutePurpose
/v1/orgsOrganizations, members, roles
/v1/reposRepository discovery and creation
/v1/repos/{namespace}/{repo}/refs · commits · releasesVersions: branches, immutable commits, signed releases
/v1/repos/{namespace}/{repo}/manifests · objects · assetsContent-addressed artifacts (sha256 digests)
/v1/repos/{namespace}/{repo}/products/{scheme}:{id}One product, e.g. products/gtin:04012345678901
/v1/repos/{namespace}/{repo}/classes/{code}One class, e.g. classes/EC004532
/v1/repos/{namespace}/{repo}/mappings?source={ns}:{code}Mappings for a source identifier
/v1/repos/{namespace}/{repo}/changes?after={cursor}Change feed for synchronization
/v1/repos/{namespace}/{repo}/quality · access-requests · queryQuality results, entitlements, constrained queries
/v1/products/resolve?identifier=gtin:…Assertions for one identifier across repositories
/v1/upload-sessions · /v1/jobs · /v1/webhooks · /v1/connectors · /v1/sync-runsPublishing, long-running jobs, events, integrations

Conventions

  • Cursor pagination for changing collections; cursors are opaque — never derive offsets from them.
  • ETag and conditional requests; ref updates use If-Match and fail with 409 on a concurrent change.
  • Idempotency-Key on every retried mutation.
  • Errors are RFC 9457 problem details with stable type URIs and a request ID.
  • Long operations return a job resource; large bytes move through time-limited object grants.
Resolve an identifier
curl -s "https://api.product.cloud/v1/products/resolve?identifier=gtin:04012345678901"

Publishing

Start in the browser with a sample file to get a validated product.yaml draft, then publish the full dataset with the CLI. Pushes upload only missing objects; the hub re-verifies every digest before advancing a ref.

Publisher workflow
product auth login
product repo create acme/power-tools-eu --type product --restricted
product init --type product
product import bmecat catalog.xml --output data/
product validate
product quality check --policy quality/rules.yaml
product add product.yaml README.md data/ schemas/ quality/
product commit -m "Publish September 2026 catalog"
product push origin main
product release create 2026.09 --sign --notes CHANGELOG.md

Formats

CSV import

Identity columns are gtin (or ean), mpn, brand (or manufacturer), and name. Every other column is an attribute whose header may carry a unit and a language: property[unit]@lang. Empty cells produce no attribute; values are kept verbatim.

catalog.csv
gtin,mpn,brand,name,rated_voltage[V],weight[kg],class:etim,description@de,description@en
04012345678901,GSR-18,ACME,Cordless drill driver 18 V,230,2.35,EC004532,Akkubohrschrauber,Cordless drill driver

BMEcat 2005 (INTERNATIONAL_PID type="gtin", ETIM features) is imported with product import bmecat. Canonical tables are stored as Parquet; exports include JSONL, CSV, and BMEcat.

Canonical JSON and digests

Commits and manifests are identified by sha256: digests of their canonical JSON: a subset of RFC 8785 with object members sorted by UTF-16 code units, no insignificant whitespace, minimal string escaping, and integers only (decimals travel as strings). The golden vectors in specs/repository/0.1/golden-vectors.json are reproduced by both the Rust implementation and an independent TypeScript verifier; every client should pass them.