Cart metafield sent in cartCreate input doesn't reach the order, but cartMetafieldsSet does

I want a cart metafield to end up on the order (Storefront API 2026-04, cart-to-order copy). I have an order metafield definition with cartToOrderCopyable enabled, type json, key my_key.

Works: after the cart exists, I call cartMetafieldsSet with my app’s Storefront token and a simple key (my_key). The value appears on the order in the admin.

Doesn’t work: for a cart created by the theme’s own cartCreate call (Buy now button), I add the same metafield to the request before it is sent:

"input": {
  "lines": [{ "merchandiseId": "gid://shopify/ProductVariant/123", "quantity": 1 }],
  "metafields": [{ "key": "my_key", "type": "json", "value": "{\"a\":1}" }]
}

I confirmed in the Network tab that the metafield is in the payload. There are no errors or userErrors, but the order has no metafield.

My guess is namespaces. The docs for CartMetafieldsSetInput.key say a simple key uses “the default app-reserved namespace”. The theme’s cartCreate uses a different Storefront token, so it may write to a different app-reserved namespace than my order definition expects.

Questions:

  1. For a simple key, does the namespace depend on the app that owns the Storefront access token?
  2. Can I use a composite key like custom.my_key in CartInputMetafieldInput? The docs don’t mention it. Would the order definition need Storefront write access?
  3. Is there another supported way to attach data to a cart created by a third party’s cartCreate call so it reaches the order?

I think the namespace is tied to the app whose token makes the call, so the theme’s cartCreate and your app would write to different namespaces.

I’m not sure a composite key is accepted on that input, so I’d test it on a fresh cart before relying on it.