Personalization Migration Guide#
To make it easier for sellers with personalizable listings to collect the information they need from buyers and more efficiently process personalizable orders, we have replaced the single free-text personalization field with an architecture that supports multiple, typed personalization inputs: text inputs, dropdowns, and file upload questions. More information about the reasoning behind this project can be found in the GitHub announcement.
info
What changed
- Personalization is now managed through a dedicated data structure and a suite of personalization-specific endpoints (
getListingPersonalization,updateListingPersonalization, anddeleteListingPersonalization). - Listings support up to 5 personalization questions across 3 question types: text input, dropdown, and file upload.
- The legacy personalization fields (
personalization_is_required,personalization_char_count_max, andpersonalization_instructions) have been deprecated. Listing create/update requests that include these fields will return an error, and they are no longer returned when reading listing data.
For detailed examples of every request and response described here, see the Examples page.
Required changes#
To ensure your integration is compatible with personalization, you must make the following changes.
If you read personalization data on listings:#
- Update your integration to use the new personalization data structure (details below).
- Fetch listing personalization data via the new
getListingPersonalizationendpoint, or by calling one of getListingsByShop, getListing, or getListingsByListingIds withpersonalizationin theincludesquery param. - Your integration must correctly display multiple questions across all three question types (text input, dropdown, and file upload).
- The
is_personalizableproperty will continue to be returned from the current listing endpoints.
If you read personalization data on transactions:#
- Personalization data continues to be returned in the transaction
variationsarray in the existing format. If your integration relies on theformatted_namebeing "Personalization" or on there being a single item withproperty_id: 54, it must be updated (see Reading transaction personalization data).
If you write personalization data on listings:#
- Update your integration to use the new personalization POST and DELETE endpoints (
updateListingPersonalizationanddeleteListingPersonalization). Requests to the POST endpoint fully replace the existing personalization data on the listing. - Stop sending legacy personalization fields on listing create and update requests.
- To write multiple questions and/or new question types, follow the constraints in Writing listing personalization data.
tip
How to test: Use your normal process and be sure to follow these guidelines.
For guidance on how personalization works in Etsyweb, see the Help Center article: How to Offer Personalized Listings.
Reading listing personalization data#
Listing personalization data can be fetched through the dedicated GET endpoint or through the listing endpoints that return associations.
We are introducing a 120 character limit on the instructions field. Existing instructions values that exceed this limit are still returned in full by GET requests and are not automatically truncated. However, any update to these questions via a POST request must comply with the 120 character limit.
Through the dedicated personalization GET endpoint#
The getListingPersonalization endpoint (GET https://api.etsy.com/v3/application/listings/{listing_id}/personalization) fetches personalization data by listing_id. It returns a personalization_questions array. If the listing has no personalization configured, the array is empty.
The question data structure supports all question types:
Via endpoints that return listings with associations#
You can retrieve the personalization data for a listing from the following endpoints by appending the ?includes=personalization query param:
- getListingsByShop -
GET /v3/application/shops/{shop_id}/listings - getListing -
GET /v3/application/listings/{listing_id} - getListingsByListingIds -
GET /v3/application/listings/batch
The response body includes a personalization key containing a possibly empty personalization_questions array. The is_personalizable property continues to be returned at the base listing level:
note
The legacy fields (personalization_is_required, personalization_char_count_max, and personalization_instructions) are no longer returned by these endpoints.
Reading transaction personalization data#
Personalization data for a transaction is returned (if present) as part of the variations array on a transaction object:
Transaction personalization continues to be returned in this format, but be advised of the following changes:
- The
formatted_namemay be a seller-configured value, not necessarily"Personalization". - There may be multiple objects with
property_id: 54. - For file uploads, the
formatted_valuewill be a URL.
Writing listing personalization data#
The updateListingPersonalization endpoint (POST https://api.etsy.com/v3/application/shops/{shop_id}/listings/{listing_id}/personalization) creates or updates personalization data for a listing.
note
This endpoint fully replaces the existing personalization data on the listing with the data you send. To create personalization you must first have an existing listing; if you don't have one, create it with createDraftListing first.
The endpoint accepts an array of up to 5 personalization_questions and supports all question types:
warning
When you write multiple questions and new question types, you must also append ?supports_multiple_personalization_questions=true when calling this endpoint. This lets us track adoption and prevents inadvertent overwrites of seller data from non-updated apps. Without this query param, attempts to write data that would delete previously configured personalization questions will fail with a 409 Conflict error.
Adding the param without updating your application can lead to deleting data provided by the seller on Etsyweb.
Please note the following constraints:
- The
personalization_questionsarray must contain between 1 and 5 elements. - At most one upload-type question (either
unlabeled_uploadorlabeled_upload) may be sent per listing.
There are also field-level constraints:
question_text- Must be between 1 and 45 characters
- Must begin with a letter or number
- Must not contain more than one word starting with 3+ capitalized letters
instructions- Must be empty or
nullfor dropdowns - Optional for the other question types
- Must not exceed 120 characters when provided (requests will fail validation otherwise)
- Must begin with a letter or number
- Must not contain more than one word starting with 3+ capitalized letters
- Must be empty or
max_allowed_characters- Required for
text_inputquestions; not allowed for other question types - Must be between 1 and 1024
- Required for
max_allowed_files- Required for upload questions (either labeled or unlabeled); not allowed for other question types
- Must be between 1 and 10
- For
labeled_uploadquestions,max_allowed_filesmust be 2 or more
options- Required for
dropdownandlabeled_uploadquestions; not allowed for other question types - For dropdowns:
- Must contain 1 - 30 options
- Each label must be 1 - 20 characters
- Labels must be unique within the question
- For labeled uploads:
- Length must equal
max_allowed_files - Each label must be 1 - 45 characters
- Length must equal
- Required for
question_id- Optional, but encouraged if you are updating or adding to existing personalization on a listing (example)
Deleting personalization from a listing#
The deleteListingPersonalization endpoint (DELETE https://api.etsy.com/v3/application/shops/{shop_id}/listings/{listing_id}/personalization) turns off personalization for a listing and removes the associated data.
The is_personalizable property will be set to false on the main listing record as a result of this action.
For detailed examples of each of these operations, see the Examples page.