Submit orders with an API key

Version 1.0 · Updated 2026-10-12

This page moves order submission onto a WHCC API key: create the order, confirm it, and receive order events through an event subscription. Use it on its own if you build OrderImport bodies yourself, or as the second half of Use editors with an API key, submitting the order an editor export gives you. Your order body doesn't change. The routes you send it to and the way you authenticate do.

This page is for an existing integration being moved onto an API key. If you are building something new, start at the Quick Start: new integrations use the WHCC API, which is a separate flow.

Hosts

https://apis-stage.whcc.com/api/v1

Sandbox. Build and test here first. Sandbox and production keys are separate.

https://apis.whcc.com/api/v1

Production. A confirmed order here is a real, billable order.

Every path on this page is relative to that base, so /oas/orders/create means https://apis-stage.whcc.com/api/v1/oas/orders/create. Send API-key requests to the host above, not to the host your consumer-credential integration calls. The examples show the sandbox host and run as written with a sandbox key. On production, only the host and the key change.

The credential

Send the API key as a bearer token on every request. There is no token exchange, no access-token call (/auth/access-token on the Editor API, /api/AccessToken on the Order Submit API), and no token expiry to manage.

1
Authorization: Bearer <YOUR_API_KEY>

Keep the key out of browsers, logs and source control. API Key Security covers where to store it and how to rotate it.

Your key carries two scopes

This flow needs a key granted both apikey and apikey:oas.

apikey

Ordinary partner access: event subscriptions, the fulfillment routes, and GET /discovery.

apikey:oas

The two ordering routes below: create and confirm.

A request whose key doesn't carry a scope the route requires is refused with 403, with no code field to branch on. A one-field {"message":"Forbidden"} or {"message":"Unauthorized"} body comes from the gateway, before the request reached the service — check the host and the key.

Checking what your key reaches

GET /discovery lists the operations the key you present can call, with the scope each one requires, and returns the key's own scopes in grantedScopes. Discover routes for your key documents the response. Call it first: the legacy routes should appear under operations.

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

What this flow calls

Each row names a route, the scope it requires, and the step that calls it.

GET /discovery

POST /oas/orders/create

apikey:oas · 1. Create

POST /oas/orders/{confirmationId}/confirm

apikey:oas · 2. Confirm

POST /fulfillment/event-subscriptions

apikey · 3. Events

POST /fulfillment/event-subscriptions/{id}/test

apikey · 3. Events

POST /fulfillment/event-subscriptions/{id}/enable

apikey · 3. Events

The three event-subscription rows are the ones this walkthrough calls. The resource has more — list, read, replace, disable, delete and the event-type catalogue — and all of them take apikey. Event Subscriptions is the full list.

Replacing your current calls

The Order Submit API (Legacy) routes don't accept an API key. Replace each call you make today with its API key equivalent.

Legacy endpoint With an API key
POST /api/OrderImportPOST /oas/orders/create
POST /api/OrderImport/Submit/{ConfirmationID}POST /oas/orders/{confirmationId}/confirm
POST /api/callback/createAn event subscription
GET /api/AccessTokenNot needed. Send the API key as the bearer token.

Step 1: Create the order

POST /oas/orders/create takes the OrderImport body you already build and returns a ConfirmationID. The schema is unchanged and documented field by field under Order Import. You don't call the Order Submit API's own import and submit routes on an API key.

1
2
3
4
5
curl https://apis-stage.whcc.com/api/v1/oas/orders/create \
	-H "Authorization: Bearer <YOUR_API_KEY>" \
	-H "Accept: application/json" \
	-H "Content-Type: application/json" \
	-d @order.json

order.json is either the OrderImport body you send today, or the order object from an editor export with the fields it left null filled in. The order is attributed to the account your key resolves to. Nothing in the body changes that.

Step 2: Confirm the order

An order is not produced until it is confirmed. POST /oas/orders/{confirmationId}/confirm takes no body.

1
2
curl -X POST https://apis-stage.whcc.com/api/v1/oas/orders/a3ff9b4a-3112-4101-88ab-6ba025fd7600/confirm \
	-H "Authorization: Bearer <YOUR_API_KEY>"

The response fields are the Order Submit API's, documented under Order Submit.

What a refusal on these two routes looks like

The two ordering routes share an error contract that is narrower than the rest of this API:

400

Almost everything. A malformed body, a rejected field, an editor that doesn't exist, and an upstream failure all arrive as 400. Read the message rather than branching on the status.

403

Either your key doesn't carry apikey:oas, or the request points at an account that isn't yours. These are passed through rather than flattened, so a 403 here is always one of those two.

500

Something is wrong with the key itself rather than with your request. Retrying the same call won't help. Contact WHCC support.

Step 3: Receive order events

With an API key, order events arrive through an event subscription. You create it yourself through the WHCC API, and it receives events for every order on your account.

Event Subscriptions documents every route and field. This section covers what you need to make the switch.

The Editor API's POST /oas/webhooks/create and POST /oas/webhooks/verify don't accept an API key. Use an event subscription instead.

Your first subscription

1
2
3
4
5
6
7
8
9
10
11
12
curl https://apis-stage.whcc.com/api/v1/fulfillment/event-subscriptions \
	-H "Authorization: Bearer <YOUR_API_KEY>" \
	-H "Content-Type: application/json" \
	-H "Idempotency-Key: $(uuidgen)" \
	-d '{
			"destination": {
				"type": "webhook",
				"callbackUri": "https://path.to.your/webhook/endpoint"
			},
			"eventTypes": ["order.accepted", "order.rejected", "order.shipped"],
			"description": "Production endpoint"
		}'

Store signingSecret from the 201, deploy your handler, send a test event, then enable the subscription. Event Subscriptions explains each of those, and why an Idempotency-Key on create is worth sending.

Your Order Submit callback keeps working until you remove it. While both are live, your endpoint receives each event twice, signed with different secrets. If your callback is on V1, the two copies can also be named differently: an accepted order arrives as order.received on the callback and order.accepted on the subscription. Map the names to one vocabulary before you deduplicate on event type, or every event is processed twice; Version 1 subscriptions lists the mapping. If you also have an Order Submit callback covers deduplicating them, and Verifying a delivery covers checking signatures.

What's Next

Event Subscriptions — the full reference for step 3.

Security and Signatures — verify WHCC-Signature on a delivery.

Delivery, Retries & Idempotency — the retry schedule, the response timeout, and why your handler must deduplicate.

API Key Security — where to keep the key.

Back to Top 👆
Get in Touch

Interested in integrating with WHCC? Tell us more about what you’re looking for and we’ll be in touch.