Personalization Add-On Pricing#

Overview#

We are introducing support for add-on pricing on optional text input personalization questions. This enhancement enables sellers to apply an additional charge when a buyer provides optional text personalization for a listing. Initially, add-on pricing will not be supported in other personalization question types.

To support a smooth rollout, this change will remain backward compatible for the first 30 days after release. After the migration period ends, integrations will be expected to handle text box add-on pricing explicitly in certain update scenarios.

Required Changes#

If you read listing personalization data:#

  • Update your integration to read and display any add_on_price data associated with a personalization question.
  • No changes are being made to transaction or receipt data at this time.

If you write listing personalization data:#

  • Update your integration to allow sellers to configure add_on_price data for optional text questions.
    • Add-on prices are currently only allowed for questions of type text_input with required: false.
  • To avoid errors after the 30-day migration period ends, when updating questions with add-on prices configured, you must send an add_on_price key as follows:
    • To preserve the existing add-on price, send the current value (formatted as a float).
    • To change the add-on price, send a new, valid value.
    • To remove the add-on price from the question, send an explicit 0 or null.

Rollout & Migration Timeline#

Add-on pricing migration timeline

Days 0–30#

During the first 30 days after release, add_on_price will be available on optional text_input personalization questions as an optional field and will remain fully backward compatible. No breaking changes will be introduced.

After Day 30#

Update behavior becomes stricter for text personalization questions that already have an add-on price configured. We will return a validation error if the add_on_price is not sent, and there is existing price data on the question being updated.

Create behavior is unaffected — if add_on_price is omitted or null on create, no add-on price is configured.

Read Operations#

Get personalization questions#

Endpoints: getListingPersonalization, getListingsByShop, getListing, getListingsByListingIds

For read operations, the add_on_price field is returned only when applicable.

The API returns null for:

  • Personalization questions whose type is not text_input, including dropdown, labeled file upload, and unlabeled file upload questions
  • Text personalization questions that do not have an add-on price configured

When an add-on price is configured for a text question, the API returns a Money object, which is the standard format for pricing data in the rest of our endpoints.

{
"question_id": 12345,
"question_type": "text_input",
"question_text": "Enter your custom text",
"add_on_price": {
"amount": 5000,
"currency_code": "USD",
"divisor": 100
}
}

The returned Money object includes:

  • amount: the price value in the currency's base unit
  • currency_code: the shop currency
  • divisor: the number of decimal places used by the currency

Read behavior is unchanged after the migration period ends.

Write Operations#

Create or update personalization questions#

Endpoint: updateListingPersonalization

add_on_price is an optional float field on write requests. When provided, the value must be positive and fall within the supported range of $0.20 to $500.00 USD.

During the migration period, the API will apply the following behavior:

  • If you haven't adopted the change and the add_on_price key is omitted:

    • Create requests (no question_id): no add-on price will be configured.
    • Update requests (with a matching question_id): any existing add-on price on that question is preserved. A question_id must be provided for this carry-over to apply — questions submitted without one are treated as new and will not inherit any existing add-on price. Note that only optional text_input questions (required: false) are eligible for add-on pricing.
  • If add_on_price is set to 0 or null:

    • any existing add-on price is explicitly removed.
  • If add_on_price is set to a float value:

    • the add-on price is created or updated to the specified value.

    Note: The currency for add_on_price is derived from the shop's configured currency to avoid inconsistencies between price data and shop settings. You can retrieve the shop currency from the getShop endpoint.

  • If the add_on_price is outside the valid range ($0.20 - $500.00 USD or equivalent), a validation error will be returned
  • If the question is required and a float price is sent, a validation error will be returned

Example: Set an add-on price#

{
"personalization_questions": [
{
"question_id": 12345,
"question_text": "Enter your custom text",
"add_on_price": 50.00,
"max_allowed_characters": 100
}
]
}

Example: Remove an add-on price#

{
"personalization_questions": [
{
"question_id": 12345,
"question_text": "Enter your custom text",
"add_on_price": 0,
"max_allowed_characters": 100
}
]
}
{
"personalization_questions": [
{
"question_id": 12345,
"question_text": "Enter your custom text",
"add_on_price": null,
"max_allowed_characters": 100
}
]
}

Example: Add-on price omitted when updating a question with an existing add-on price#

Request:

{
"personalization_questions": [
{
"question_id": 12345,
"question_text": "Enter your custom text",
"max_allowed_characters": 100
}
]
}

Response (during migration period — existing price is preserved):

{
"personalization_questions": [
{
"question_id": 12345,
"question_text": "Enter your custom text",
"max_allowed_characters": 100,
"add_on_price": {
"amount": 5000,
"currency_code": "USD",
"divisor": 100
}
}
]
}

Write Operations After Day 30#

Endpoint: updateListingPersonalization

If you update a text personalization question that already has an existing add-on price, you must provide add_on_price explicitly. If it is omitted and the question being updated has an existing price, the API will return a validation error and reject the request.

This ensures that integrations explicitly preserve, update, or remove add-on pricing rather than relying on migration-period fallback behavior.

After Day 30:

  • To preserve the current add_on_price, send the existing value.
  • To update the add_on_price, send the new value.
  • To remove the add_on_price, send 0 or null.

Create behavior remains unchanged — if add_on_price is omitted or null, no add-on price is configured.

Example error response when updating a text question with existing price and no explicit add-on price in the request#

Payload:#

{
"personalization_questions": [
{
"question_id": 2347238372,
"question_text": "existing text question with price",
"question_type": "text_input",
"required": false,
"max_allowed_characters": 100
}
]
}

Error response:#

{
"error": "add_on_price is required when updating a text question with an existing add-on price. To remove the price, set add_on_price to 0."
}