> Part of [WHCC Developer Documentation](https://www.whcc.com/developer/llms.txt)

# WHCC API Reference

Version 1.8 &middot; Updated 2026-10-09

The WHCC API lets your application choose print products, build them with your customers' photos, check pricing, and submit orders with one API key. Start with the [Quick Start](https://www.whcc.com/developer/docs/quick-start/index.html.md) to walk through the flow, then use these pages for field details and additional options.

## What you can order

The catalog is the source of truth. `GET /v1/catalog/products` lists every product your key can see, and each one carries a `completion` field that says whether this API can build it:

- **`"completion": "api"`**: Build, price and order it through this API with no editor session. Stock products, and anything the simple editor offers, are here. Filter on this value.
- **`"completion": "editor"`**: Needs a design finished in the full WHCC editor, so this API can't build it yet.

Filter on `completion`, not on category or name, because the set grows over time. The [Quick Start](https://www.whcc.com/developer/docs/quick-start/#step-1) shows the catalog call, and [Response Bodies](https://www.whcc.com/developer/docs/api/responses/#products) has the full product shape. For a browsable overview of the range, see [Products](https://www.whcc.com/developer/products/index.html.md).

## How a submission becomes orders

A **submission** is the request you send. WHCC accepts it, then creates one or more **orders**. Each order can have more than one **fulfillment order** for production and shipping.

Create an [event subscription](https://www.whcc.com/developer/docs/api/event-subscriptions/index.html.md) and WHCC tells you when each order is accepted, rejected, shipped or cancelled; don't poll for it. Save the submission ID to confirm the submission produced orders and to reconcile, and follow each order's `actions.fulfillment` link when you need its fulfillment orders, production status and shipments. See [Submission Lifecycle](https://www.whcc.com/developer/docs/api/submission-lifecycle/index.html.md) for how these fit together.

### Which order endpoint should you use?

- **`GET /v1/commerce/submissions/{submissionId}`**: Check the request you sent: whether it is still being submitted, whether all or some orders were placed, and any placement failures. This route takes the submission ID returned by `POST /v1/commerce/submissions`.
- **`GET /v1/fulfillment/orders`**: Find the fulfillment orders created from a submission. Follow the submission's `actions.fulfillment.url`, or an individual `orders[]` entry's link, to get the right filtered list. One link may return several fulfillment orders.
- **`GET /v1/fulfillment/orders/{id}`**: Read one fulfillment order's current production status, status history, and shipments. Follow `items[].links.self` from the fulfillment list; the route also accepts a fulfillment order ID or WHCC order number. See [Orders & Fulfillment](https://www.whcc.com/developer/docs/api/fulfillment/index.html.md).

## Hosts and authentication

- **`https://apis-stage.whcc.com/api`**: **Sandbox.** Our test environment: build and test here first, with a sandbox API key.
- **`https://apis.whcc.com/api`**: **Production.** Orders submitted here are real, and you'll be billed for them.

The examples on these pages use the sandbox host, so they run as written with a sandbox key. On production, only the host and the key change. Every request carries your API key as a bearer token:

```shell
curl https://apis-stage.whcc.com/api/v1/catalog/products \
	-H "Authorization: Bearer <YOUR_API_KEY>"
```

Send `WHCC-API-Version: 2026-10` on every request to stay on a known API version; see [API Versions](https://www.whcc.com/developer/docs/api/versioning/index.html.md). Keys are issued by WHCC and bound to one account, and sandbox and production keys are separate. See [API Key Security](https://www.whcc.com/developer/docs/api/api-key-security/index.html.md) for how to store a key, hand one to an AI agent, and get one revoked if it leaks. A missing or unrecognized key is rejected before your request reaches the API; see [Errors & Rate Limits](https://www.whcc.com/developer/docs/api/errors/index.html.md) for the exact bodies.

## Discover routes for your key

`GET /v1/discovery` lists the operations your key can reach, including each route's method and path. Use it when you begin an integration and when you change keys. A listed route can still reject a request because of its data or the resource you're trying to use.

```shell
curl https://apis-stage.whcc.com/api/v1/discovery \
	-H "Authorization: Bearer <YOUR_API_KEY>"
```

#### Example response (trimmed)

```json
{
	"contract": "whcc.discovery",
	"contractVersion": "1",
	"generatedAt": "2026-10-01T14:43:08.164Z",
	"grantedScopes": ["apikey"],
	"semantics": ["…"],
	"sources": [
		{ "service": "prospector", "status": "fresh", "generatedAt": "2026-10-01T14:43:08.164Z" },
		{ "service": "fulfillment", "status": "fresh", "generatedAt": "…", "fetchedAt": "…" }
	],
	"links": {
		"service-desc": "https://apis.whcc.com/api/swagger.json",
		"service-doc": "https://apis.whcc.com/api/documentation"
	},
	"operations": [
		{
			"service": "prospector",
			"method": "GET",
			"path": "/api/v1/catalog/products",
			"scopes": { "anyOf": ["apikey"] },
			"tags": ["api", "authenticated", "catalog"],
			"description": "Lists the products your organization can sell",
			"notes": ["…"],
			"writes": false
		},
		{ "…": "trimmed" }
	]
}
```

- **`grantedScopes`**: The scopes your key carries. A partner key carries `apikey`.
- **`environment`**: The environment that answered, such as `dev`.
- **`semantics[]`**: Plain sentences on how to read the list. A listed operation only means your key's scopes admit the route. The route can still refuse the call, or need a product or resource your account doesn't have.
- **`sources[]`**: One entry for each service the list was built from, such as `prospector` and `fulfillment`, with its `status` and when its listing was generated.
- **`links`**: `service-desc` (the machine-readable API description) and `service-doc` (the Swagger UI). These are absolute URLs. Each operation also has its own `links.service-desc`, which is a path on the host (such as `/api/v1/fulfillment/openapi.yaml`) for Fulfillment routes and an absolute URL for the others.
- **`operations[]`**: One entry for each route your key can call. `path` is the full path on the host, so it starts with `/api`, unlike the paths on these pages, which are relative to the [base URL](https://www.whcc.com/developer/docs/api/#hosts).
- **`operations[].service, tags`**: The service behind the route (`prospector` or `fulfillment`) and labels for grouping. `tags` is empty on Fulfillment routes.
- **`operations[].scopes`**: The scopes that open the route. `anyOf` needs one of the listed scopes. Your key can call the route when `apikey` is in the list.
- **`operations[].writes, irreversible`**: `writes` is `true` when a successful call changes something, such as building a product or placing a submission. `irreversible: true` marks a change that can't be undone, such as canceling an order. Reads and calculate carry `writes: false`.
- **`operations[].description, notes`**: What the route does, for people to read. Don't parse them: the wording can change.

Discovery describes access for the key you present; [Swagger UI](https://www.whcc.com/developer/docs/api/#swagger) shows request and response schemas. Discovery can list a route these pages don't cover. Build on the routes documented here. If Discovery returns `403` for your key, ask WHCC which routes are available to it.

## Swagger reference

Explore the API in Swagger UI: [production](https://apis.whcc.com/api/documentation#/) · [sandbox](https://apis-stage.whcc.com/api/documentation#/).

## Follow links between calls

Many responses include an `actions` object. Each action names a useful next request and supplies its `url` and `method`; some also include `instructions`. These links carry the right product reference or order filter for the response you're reading, so you can follow them as you move through the API.

- **`actions.detail`**: From a catalog result to that product's full details.
- **`actions.create`**: From a product to the call that builds a configured product.
- **`actions.fulfillment`**: From a submission or one of its orders to the matching fulfillment orders.

When a response carries an action, its URL is absolute, on the host you called, and it is the URL to use: don't join it to the base URL. Catalog, build, poll and submission responses all carry them. Calculate and the submission read have no action pointing at them: for those two, build the URL from the base and the documented path. An action can point at a route your key can't call, and [Discovery](https://www.whcc.com/developer/docs/api/#discovery) tells you which ones it can. When an action carries `instructions`, they tell you what that request needs. To check product readiness, follow `actions.poll` as shown in [Quick Start Step 4](https://www.whcc.com/developer/docs/quick-start/#step-4). Once the items are ready, [calculate](https://www.whcc.com/developer/docs/quick-start/#step-5) with your shipping details to check the price and validate the submission. See the [product detail](https://www.whcc.com/developer/docs/api/responses/#product-detail) and [submission](https://www.whcc.com/developer/docs/api/responses/#submission) examples.

## Endpoints

Discover products in the catalog, build each one as a configured product, poll until it's ready, check the price with calculate, then submit. After that, the fulfillment routes read, cancel and re-address the orders, and an event subscription tells you when each one changes.

- **`GET /v1/catalog/products`**: List the product catalog for your account. [Quick Start Step 1](https://www.whcc.com/developer/docs/quick-start/#step-1) · [response body](https://www.whcc.com/developer/docs/api/responses/#products)
- **`GET /v1/catalog/products/{ref}`**: One product's full details, including `configuration.fields[]` for choosing options. [Quick Start Step 2](https://www.whcc.com/developer/docs/quick-start/#step-2) · [response body](https://www.whcc.com/developer/docs/api/responses/#product-detail)
- **`POST /v1/commerce/configured-products`**: **Build.** Create a priced product from your selections and images. It is a draft, not an order. Once every item is ready, its `actions.submit` points at the submit route below.
- **`GET /v1/commerce/configured-products?ids=…`**: **Poll.** Check whether the configured products you built are ready to submit. Polling never creates anything; up to 50 ids per call. [Quick Start Step 4](https://www.whcc.com/developer/docs/quick-start/#step-4)
- **`POST /v1/commerce/configured-products/{configuredProductId}/edit-link`**: Get a link that opens a configured product in a WHCC editor. The link is a credential. [Quick Start Step 4](https://www.whcc.com/developer/docs/quick-start/#edit-link)
- **`POST /v1/commerce/submissions`**: **Submit.** Starts a real, billable order. A submission that validates answers `202`. See [Submission Lifecycle](https://www.whcc.com/developer/docs/api/submission-lifecycle/index.html.md). [shipping options](https://www.whcc.com/developer/docs/api/shipping/index.html.md) · [metadata & reference](https://www.whcc.com/developer/docs/api/metadata/index.html.md)
- **`POST /v1/commerce/submissions/calculate`**: Price and check a basket without submitting it. Calculate doesn't create anything or place an order. [response body](https://www.whcc.com/developer/docs/api/responses/#calculate)
- **`GET /v1/commerce/submissions`**: List your submissions as short rows for lookups and reconciliation. [response body](https://www.whcc.com/developer/docs/api/responses/#submission-list)
- **`GET /v1/commerce/submissions/{submissionId}`**: One submission in full, the same shape `POST /v1/commerce/submissions` also returns. [response body](https://www.whcc.com/developer/docs/api/responses/#submission)
- **`GET /v1/fulfillment/orders`**: List the orders a submission produced. Follow the submission's `actions.fulfillment` link to get the right filtered list. [Orders & Fulfillment](https://www.whcc.com/developer/docs/api/fulfillment/#list)
- **`GET /v1/fulfillment/orders/{id}`**: One order's production status, status history and shipments. [Orders & Fulfillment](https://www.whcc.com/developer/docs/api/fulfillment/#order)
- **`POST /v1/fulfillment/orders/{id}/cancel-actions`**: Begin canceling an order; a second call completes it with the token this one returns. [Canceling an order](https://www.whcc.com/developer/docs/api/fulfillment/#cancel)
- **`PUT /v1/fulfillment/orders/{id}/shipping`**: Change where an order ships and which option carries it, with a preview route to price the change first. [Changing where an order ships](https://www.whcc.com/developer/docs/api/fulfillment/#shipping)
- **`POST /v1/fulfillment/event-subscriptions`**: Register a URL that WHCC calls when an order is accepted, rejected, shipped or canceled. This is how you follow order status. [Event Subscriptions](https://www.whcc.com/developer/docs/api/event-subscriptions/index.html.md)

## Reference pages

- [Orders & Fulfillment](https://www.whcc.com/developer/docs/api/fulfillment/index.html.md): the orders a submission produced: list and read them, cancel one, change where it ships, and read your account.
- [Event Subscriptions](https://www.whcc.com/developer/docs/api/event-subscriptions/index.html.md): register a URL for order events, verify deliveries, send a test event, and rotate the signing secret.
- [Response Bodies](https://www.whcc.com/developer/docs/api/responses/index.html.md): real responses for the catalog list and detail, a submission, the submission list, and calculate, with what each field means.
- [Shipping](https://www.whcc.com/developer/docs/api/shipping/index.html.md): the shipping object, and how to find the methods an address offers.
- [Metadata & Reference](https://www.whcc.com/developer/docs/api/metadata/index.html.md): carrying your own identifiers on a submission: the `metadata` map's limits and the 32-character `reference` that reaches fulfillment paperwork and the shipping label.
- [Errors & Rate Limits](https://www.whcc.com/developer/docs/api/errors/index.html.md): worked examples of both error shapes, every `submission.*` code with what to do about it, and how to handle throttling.
- [Submission Lifecycle](https://www.whcc.com/developer/docs/api/submission-lifecycle/index.html.md): why submitting is asynchronous, the `Idempotency-Key` header, following order status, and what each submission `status` means.
- [API Key Security](https://www.whcc.com/developer/docs/api/api-key-security/index.html.md): where to keep your key and what to do if it is exposed.
- [Build It with an Agent](https://www.whcc.com/developer/docs/api/ai-agents/index.html.md): a starting prompt that takes an AI coding agent from zero to a sandbox order, and what to check after the run.