Marketplace APIs 8 min read

Getting Personalisation Text Out of Amazon, Etsy and eBay (Three APIs, Three Answers)

A buyer typed an engraving into a product page and your fulfilment team needs those exact characters. Every marketplace delivers them differently — Amazon hides them in a ZIP behind a signed URL, Etsy puts them inline, and eBay's Fulfillment API doesn't return them at all. Here's where to find them, and the trap in Amazon's payload that silently loses text.

Updated Aug 2026
Getting Personalisation Text Out of Amazon, Etsy and eBay (Three APIs, Three Answers)

The Same Business Requirement, Three Unrelated APIs #

If you sell anything engraved, printed, monogrammed or made to order, one field decides whether the order can be fulfilled: the exact text the buyer typed. Get it wrong and you ship a physical object with a misspelled name on it.

There is no cross-marketplace standard for this. Not a loose one — none at all. Three marketplaces, three unrelated mechanisms, and one of them doesn't expose it in the modern API at all:

Marketplace Where the text lives Shape Extra calls?
Amazon CustomBuyerCustomizedInfo.CustomizedURLSigned URL → ZIP → JSON + SVGYes — restricted token, then download
Etsytransactions[].variationsInline name/value pairsNo
eBayNot in the Fulfillment APIVariation aspects, SKU, or legacy APIDepends on how the listing is built

Amazon Custom: A ZIP Behind a Signed URL #

Amazon Custom orders carry the personalisation on the order item, not the order, and only on the buyer-info path — the same restricted endpoint that returns buyer PII:

GET /orders/v0/orders/{orderId}/orderItems/buyerInfo

That means you need a Restricted Data Token before you can see it at all. If you're getting nulls, start with the RDT flow — the personalisation field is gated by exactly the same mechanism as buyer name and address.

When it is populated, BuyerCustomizedInfo.CustomizedURL is a signed, expiring link to a ZIP. Download it promptly and store the contents; the URL will not be valid later. Inside:

  • <orderItemId>.json — the structured customisation payload, the one that matters
  • <orderItemId>.xml — the same data in XML
  • a small preview JPEG of the personalised product
  • a print-ready SVG with the buyer's text already laid out on the product surface

Sizing note: in a real catalogue that mixes personalised and plain SKUs, custom orders can be a small minority of volume — on the order of one in sixty. Sample a full window before concluding the field "doesn't work". A 90-day pull that happens to contain no custom orders looks identical to a broken integration.

The Amazon Trap: version3.0 Silently Loses Text #

This one costs real money, because it fails by omission rather than by error.

The customisation JSON contains two representations of the same order. There's customizationData, a deeply nested tree of *Customization nodes carrying exact geometry, fonts and colours; and there's version3.0.customizationInfo.surfaces[], a much flatter and more inviting structure. Naturally, everyone parses the flat one.

The problem: within version3.0, each area is typed as either TextPrinting or ImagePrinting, and Amazon decides per field which one to emit. A TextPrinting area has a text value you can read. An ImagePrinting area has an SVG and no text value at all.

In one real order, three fields were personalised — a date, a name and a sentiment line. The date came through as TextPrinting with readable text. The name and the sentiment came through as ImagePrinting: rendered into vector art, with the literal characters nowhere in that branch of the payload.

Within version3.0, TextPrinting areas expose the buyer text but ImagePrinting areas contain only an SVG, so parsing version3.0 alone loses fields version3.0.customizationInfo.surfaces[].areas[] TextPrinting has "text": "05/30/2026" readable ✓ ImagePrinting svgImage only, no "text" key text lost if you stop here ✗ Fall back to the customizationData tree for any area without a text value

So the rule is: parse version3.0 for convenience, but treat a missing text value as "look elsewhere", not as "empty". Walk the customizationData tree down to its TextCustomization leaves for anything the flat view didn't give you. And keep the SVG regardless — for a print workflow it's often more useful than the characters, because the layout, font and positioning are already resolved.

Etsy: Inline, and Watch the Parse #

Etsy is the humane one. Personalisation arrives inline on the receipt, in transactions[].variations, as name/value pairs alongside the rest of the line item. No second call, no download, no token dance.

Two things to be careful about. First, the same structure carries genuine product variations (size, colour) as well as free-text personalisation — you're matching on the property, and a listing's personalisation field is not guaranteed to be named the same way across shops. Keying on a display label that a seller can rename is fragile; key on the identifier.

Second, buyer checkout notes are a separate field (message_from_buyer on the receipt) and sellers absolutely do use it for engraving instructions even when a personalisation field exists. If your fulfilment process depends on getting this right, read both.

A parsing bug worth knowing about: it is easy to write a variation parser that keys off the wrong identifier field and silently produces empty personalisation for a subset of orders. It won't throw. It'll just quietly hand your production team blank engravings for some orders and correct ones for others — which reads as a data problem, not a code problem, and can survive a long time. Assert non-empty on orders you know are personalised.

eBay: It Is Not in the Fulfillment API #

Here's the one that surprises people. eBay's Sell Fulfillment API has no first-class buyer-personalisation field. Scan a full set of orders and you'll find variationAspects null and properties carrying only things like buyer protection and campaign flags. There is no buyer-checkout-message field in the response at all.

Which means the answer depends entirely on how the listing was built. In priority order:

  1. Listing variation. If the seller created an actual "Personalisation" or "Engraving" variation on the listing, the buyer's choice appears in lineItems[].variationAspects[] as name/value pairs. Structured, reliable — this is what you want, and it's worth asking the seller to restructure their listings to get it.
  2. SKU convention. Some sellers encode the variant in the custom SKU. Workable but brittle, and it can't carry free text.
  3. Buyer checkout message. If the seller relies on buyers typing instructions at checkout, that message exists only in the legacy Trading API, as BuyerCheckoutMessage on its GetOrders call. The modern REST Fulfillment API will not give it to you.

Option three is the expensive one: it means adding a second, legacy API integration alongside your REST one purely to read a single field. Before you scope that work, confirm with the seller which mechanism their listings actually use — the answer is frequently "we thought it was in the API" when it never was. The full response shape is in eBay's getOrders reference; connecting the account is covered in the eBay OAuth walkthrough.

Designing One Field for Three Shapes #

You need a single internal representation your fulfilment team reads, regardless of source. What has worked well:

  • Store the normalised pairs — an ordered list of {label, value} per line item, which all three sources can be mapped onto.
  • Store the raw payload too. Keep the original JSON or ZIP contents. When a print comes out wrong, the argument is settled in seconds instead of hours, and re-parsing historical orders after a bug fix becomes possible.
  • Persist the artwork. Amazon's print-ready SVG is genuinely valuable output. Fetch it at sync time, because the signed URL expires.
  • Flag "personalised but empty" loudly. A made-to-order SKU with no personalisation text is an exception that must reach a human before the item is produced — not a row that quietly reaches the production queue blank.

Running made-to-order across several marketplaces? This normalisation is the difference between a fulfilment team that trusts the system and one that double-checks every order by hand. See how the same four APIs differ on authentication, or talk to me about the integration.

FAQ #

Where is Amazon Custom personalisation data in SP-API?

On the order item, via GET /orders/v0/orders/{orderId}/orderItems/buyerInfo, in the field BuyerCustomizedInfo.CustomizedURL. That is a signed, expiring link to a ZIP containing the customisation JSON, an XML copy, a preview image and a print-ready SVG. It requires a Restricted Data Token.

Why is the buyer's engraving text missing from the Amazon customisation JSON?

Because you are probably reading only version3.0.customizationInfo.surfaces[]. Amazon emits some fields as ImagePrinting, which contains an SVG but no text value. Fall back to the customizationData tree and read its TextCustomization leaves for any field the flat view didn't provide.

Does eBay's Fulfillment API return buyer personalisation?

Not as a dedicated field. If the listing uses a variation, the value appears in lineItems[].variationAspects[]. A buyer's free-text checkout message is not in the REST Fulfillment API at all — it exists only in the legacy Trading API as BuyerCheckoutMessage.

How does Etsy return personalisation?

Inline on the receipt, in transactions[].variations as name/value pairs, with no additional API call. Buyer checkout notes come separately in message_from_buyer, and sellers often use that field for instructions too.

How long does Amazon's CustomizedURL stay valid?

It is a signed URL that expires, so treat it as single-use: download and persist the ZIP contents during the sync that discovered the order rather than storing the link for later.

Don't want to build this yourself?

I set this up for sellers and agencies every week. Book a free 30-minute audit of your Amazon data & PPC setup — you'll leave with a plan either way, whether we work together or not.

Found this helpful? Share it:

WhatsApp