Metadata & Reference

Version 1.4 · Updated 2026-10-08

Two fields carry your identifiers on a submission, and they do different jobs. metadata is a flat map of strings. You choose the keys, WHCC never reads them, and you get them back whenever you read the submission. reference is one short string that travels with the order and is printed on fulfillment paperwork and the shipping label. If you've used Stripe's metadata, ours works the same way.

Which field do I want?

metadata

map, ≤ 50 keys

Your own bookkeeping: cart IDs, customer IDs, job numbers, anything you want back exactly as you sent it. Values can be up to 500 characters. It isn't printed anywhere and can't be searched.

reference

string, ≤ 32 characters

One identifier that needs to be readable on the paperwork or the shipping label, and that WHCC support can search for.

Need to carry an identifier longer than 32 characters? Put it in metadata and send a short one as reference.

metadata

Shape and limits

type

A flat map of string keys to string values. Nested objects, arrays, numbers and booleans are rejected. Turn them into strings first.

keys per map

50

At most 50 entries in one map. The submission's map and each item's map are counted separately.

key length

40

At most 40 characters per key.

value length

500

At most 500 characters per value.

character counting

Lengths count Unicode characters (code points), not bytes. A 500-character value in any language is fine.

key syntax

Keys are case-sensitive, so orderId and orderid are two different keys. A key can't be empty, can't start with $, and can't contain ., [ or ]. Anything else is fine.

reserved keys

__proto__

The key __proto__ is reserved, here and anywhere else in the request body. A request that contains it returns 400 with code: "request.reserved_key". Every other key is fine, and WHCC doesn't read any key you set. reference is the only identifier WHCC itself uses.

Where you set it

POST /v1/commerce/submissions accepts metadata at the root of the body and on each items[] entry. An item's map is separate from the root map. Neither inherits from or overrides the other. The body below shows only the fields this page covers. A real call also needs the rest of the submission, including the required shipping object; see Quick Start Step 5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
	"items": [
		{
			"configuredProductId": "CF_bCy42bhE4xpJXXNezD2EQSkpAzrqBurvi8ICmrzmBTetrum",
			"quantity": 1,
			"metadata": {
				"lineItemId": "li_8842",
				"giftMessage": "Happy birthday!"
			}
		}
	],
	"reference": "PO-90188",
	"metadata": {
		"cartId": "cart_7f3a91",
		"customerId": "cus_4471",
		"channel": "mobile-ios"
	}
}

Calculate (POST /v1/commerce/submissions/calculate) accepts the same body, including metadata and reference, and returns them the same way.

What comes back

Every response that carries a submission returns its metadata, and each item returns its own. That includes the POST /v1/commerce/submissions response and GET /v1/commerce/submissions/{submissionId}. A map you sent comes back exactly as you sent it: same keys, same values, same order. If you left metadata out or sent null, you get an empty map {}, never null and never a missing key. You can read it without checking first. The short rows from GET /v1/commerce/submissions don't carry metadata, so fetch the submission itself when you need it.

Where it doesn't go

metadata stays with WHCC's record of your submission. It isn't sent to fulfillment, doesn't print on paperwork or the shipping label, and can't be searched. No endpoint looks a submission up by a metadata key or value. Anything that needs to be visible on the order belongs in reference. Anything you'll want to look a submission up by is best kept on your side, next to its id.

Setting metadata

omitted

metadata is optional. Leave it out and it comes back as {}.

"metadata": null

The same as leaving it out.

"metadata": { "k": null }

Rejected. Every value must be a string.

Changing metadata later

A submission's metadata can't be changed after you submit it, so send the map you want kept. Retrying with the same Idempotency-Key and different metadata returns your original submission with its original metadata, not a 409; see the Idempotency-Key header.

reference

reference

string, ≤ 32 characters

Optional. Your identifier for the submission: an order number, a PO number, a short customer name. It's returned on every read and printed on fulfillment paperwork and the shipping label. The 32 is counted in UTF-16 units, not code points as metadata is, so an emoji counts as two.

reference is capped at 32 characters. A longer value is rejected, not cut short. 32 characters is what WHCC's paperwork and labels hold, so a value that passes arrives in full. If your identifier doesn't fit, send a short one here and keep the long one in metadata.

When a submission becomes more than one WHCC order, each order carries the same reference, unchanged.

Other WHCC APIs carry the same 32-character reference and don't check the length; a longer value is cut off. POST /v1/commerce/submissions checks it for you up front.

Paperwork and labels print from the Windows-1252 character set, so characters outside it don't survive. Stick to plain ASCII for anything you need to read off a label or ask WHCC support to search for. Support's search ignores case.

Rejections

A value that breaks any rule on this page fails the whole request with a 400 Problem Details body. Each problem gets its own invalidParams entry, so one call tells you everything that's wrong. The one exception is a reserved key: it returns code: "request.reserved_key" with no invalidParams[]. Nothing is quietly cut short or dropped to make a request fit.

1
2
3
4
5
6
7
8
9
10
11
12
{
	"type": "about:blank",
	"title": "Your request parameters didn't validate.",
	"status": 400,
	"invalidParams": [
		{
			"reason": "A metadata value must be a string.",
			"name": "items.0.metadata.giftMessage"
		}
	],
	"instance": "/api/v1/commerce/submissions"
}

name is the dotted path to the value, so you can map each entry back to your body:

metadata

The map itself is wrong: too many keys, or not a flat object.

metadata.<key>

One entry in the root map is wrong. The key is too long or uses a character that isn't allowed, or the value is too long or isn't a string.

items.<i>.metadata.<key>

The same, on one item's map. <i> is the item's zero-based position in the items[] you sent.

reference

reference is longer than 32 characters.

A key rejected for containing a . (say a.b) shows up as metadata.a.b, so match the whole path against the keys you sent rather than only the last part. Build on name. reason is a sentence for people, and its wording can change. For every other error, see Errors & Rate Limits.

What's Next

Place a submission end to end in the Quick Start, or see the full submission on the Response Bodies page.

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.