For AI agents and LLMs: a structured documentation index is available at /llms.txt. Every page has a Markdown sibling — append .md to any URL.

Skip to content
Docs

Work with custom data

Include your own custom information when working with checkouts and some entities in the Paddle API. Great for storing metadata or other useful information when working with third-party solutions.

AI summary

Attach structured key-value data to transactions and subscriptions to store metadata, UTM parameters, or integration identifiers — Paddle automatically propagates custom data between related entities.

  • • Pass custom_data as a valid JSON object to transactions via the API or to checkouts via Paddle.js — the data is stored against the transaction entity.
  • • Paddle automatically copies transaction custom_data to the subscription created from it, and copies subscription custom_data to all future transactions (renewals, upgrades, one-time charges).
  • • Custom data is useful for storing UTM source, CRM identifiers, RevenueCat user IDs, or any other metadata you need to link Paddle entities to your own systems.

Custom data lets you add your own key-value data to subscriptions, transactions, and some other entities in the Paddle API created using Paddle Checkout or the API.

You can use custom data for things like:

  • Capturing UTM source or marketing campaign information
  • Storing metadata or other useful information for third-party integrations

How it works

You can add custom data to transactions and subscriptions using the API or Paddle.js. Both entities have a custom_data object against them, which accepts valid key-value JSON data.

When working with a checkout, you can pass custom data in a similar way to prefilling properties. Any custom data is held against the related transaction.

Paddle shares custom data between transactions and subscriptions:

  • Paddle automatically creates a subscription for transactions with recurring prices on them. Where a transaction has custom data against it, that data is copied to the created subscription for your reference.
  • Where a subscription has custom data against it, that data is copied to any transactions created from it for things like renewals, upgrades and downgrades, and one-time charges.

Before you begin

You'll need to include Paddle.js on your page and pass a client-side token.

To open a checkout, you'll need to create products and prices and pass them to a checkout.

Pass custom data to checkout

Pass custom data to a checkout using an HTML data attribute or JavaScript property.

Pass customData to the Paddle.Checkout.open() method to add custom data to the created transaction.

JavaScript
Paddle.Checkout.open({
settings: {
theme: "light",
},
items: [
{
priceId: 'pri_01gs59hve0hrz6nyybj56z04eq',
quantity: 1
},
{
priceId: 'pri_01gs59p7rcxmzab2dm3gfqq00a',
quantity: 1
}
],
customData: {
"utm_medium": "social",
"utm_source": "linkedin",
"utm_content": "launch-video",
"integration_id": "AA-123"
},
customer: {
email: "weloveyourproduct@paddle.com",
address: {
countryCode: "US",
}
}
});

For a full list of data you can pass to a checkout, see Paddle.Checkout.open()

Add a data-custom-data HTML attribute to your checkout launcher to add custom data to the created transaction.

HTML
<a
href='#'
class='paddle_button'
data-theme='light'
data-custom-data='{
"utm_medium": "social",
"utm_source": "linkedin",
"utm_content": "launch-video",
"integration_id": "AA-123"
}'
data-customer-address-country-code='US'
data-customer-email='weloveyourproduct@paddle.com'
data-items='[
{
"priceId": "pri_01gs59hve0hrz6nyybj56z04eq",
"quantity": 1
},
{
"priceId": "pri_01gs59p7rcxmzab2dm3gfqq00a",
"quantity": 1
}
]'
>
Buy Now
</a>

For a full list of HTML data attributes, see HTML data attributes

Add custom data to a transaction

You can add custom data when creating or updating a transaction. You might do this when setting up a transaction to pass to a checkout, or when working with an invoice (a manually-collected transaction).

Send a POST request to the /transactions endpoint to create a transaction, or PATCH to /transactions/{transaction_id} to update an existing one.

In your request, include custom_data as a JSON object.

This example adds UTM information to a new automatically-collected transaction.

POST /transactions
Request
{
"items": [
{
"quantity": 10,
"price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke"
}
],
"customer_id": "ctm_01gywfmzk8038netxxbhk80vwe",
"address_id": "add_01gywfmzn2dwxry2rhry1b5gj4",
"custom_data": {
"utm_source": "crm",
"utm_medium": "email",
"utm_content": "closed-deal",
"integration_id": "AA-123"
},
"collection_mode": "automatic"
}
Response (201 Created)
{
"data": {
"id": "txn_01gyyw3j6khyc2fpy3ttapzf9v",
"status": "ready",
"customer_id": "ctm_01gywfmzk8038netxxbhk80vwe",
"address_id": "add_01gywfmzn2dwxry2rhry1b5gj4",
"business_id": null,
"custom_data": {
"utm_source": "crm",
"utm_medium": "email",
"utm_content": "closed-deal",
"integration_id": "AA-123"
},
"origin": "api",
"collection_mode": "automatic",
"subscription_id": null,
"invoice_id": null,
"invoice_number": null,
"billing_details": null,
"billing_period": null,
"currency_code": "GBP",
"discount_id": null,
"created_at": "2023-04-26T13:30:06.540543605Z",
"updated_at": "2023-04-26T13:30:06.540543605Z",
"billed_at": null,
"items": [
{
"price": {
"id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"description": "Monthly (per seat)",
"product_id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"billing_cycle": {
"interval": "month",
"frequency": 1
},
"trial_period": null,
"tax_mode": "account_setting",
"unit_price": {
"amount": "3000",
"currency_code": "GBP"
},
"unit_price_overrides": [
{
"country_codes": ["US"],
"unit_price": {
"amount": "4500",
"currency_code": "USD"
}
},
{
"country_codes": ["PL"],
"unit_price": {
"amount": "8000",
"currency_code": "PLN"
}
},
{
"country_codes": ["IN"],
"unit_price": {
"amount": "100500",
"currency_code": "INR"
}
},
{
"country_codes": ["UA"],
"unit_price": {
"amount": "40000",
"currency_code": "UAH"
}
},
{
"country_codes": ["NG"],
"unit_price": {
"amount": "1400",
"currency_code": "USD"
}
}
],
"quantity": {
"minimum": 10,
"maximum": 999
},
"status": "active"
},
"quantity": 10
}
],
"details": {
"tax_rates_used": [
{
"tax_rate": "0.2",
"totals": {
"subtotal": "30000",
"discount": "0",
"tax": "6000",
"total": "36000"
}
}
],
"totals": {
"subtotal": "30000",
"tax": "6000",
"discount": "0",
"total": "36000",
"fee": null,
"credit": "0",
"balance": "36000",
"earnings": null,
"currency_code": "GBP"
},
"payout_totals": null,
"line_items": [
{
"id": "txnitm_01gyyw3ja9rt8vh0n0wvyvn59k",
"price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"quantity": 10,
"totals": {
"subtotal": "30000",
"tax": "6000",
"discount": "0",
"total": "36000"
},
"product": {
"id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"name": "ChatApp Pro",
"description": "Everything in basic, plus access to a suite of powerful tools and features designed to take your team's productivity to the next level. Enjoy advanced integrations, improved admin controls, and cross-company chat.",
"tax_category": "standard",
"image_url": "https://twemoji.maxcdn.com/v/latest/72x72/2708.png",
"status": "active"
},
"tax_rate": "0.2",
"unit_totals": {
"subtotal": "3000",
"tax": "600",
"discount": "0",
"total": "3600"
}
}
]
},
"payments": [],
"checkout": {
"url": ""
}
},
"meta": {
"request_id": "72fba838-5ece-4360-9839-99da4e628207"
}
}

Get custom data

Once added to a transaction, you can see custom data:

If a transaction creates a new subscription, the custom data is copied to the new subscription. You can see it against the subscription in the Paddle dashboard or when working with a subscription entity using the API.

  1. Go to Paddle > Customers, and find the customer who you created a transaction for.
  2. Find the transaction under the Transactions heading and click it.
  3. From the transaction overview page, click the box that contains the customer email and address. The box expands to show the full address and any custom data against the transaction.

Send a GET request to the /transactions/{transaction_id} endpoint to get the transaction. Paddle responds with the complete transaction entity including custom_data.

GET /transactions/{transaction_id}
Response (200 OK)
{
"data": {
"id": "txn_01gyyw3j6khyc2fpy3ttapzf9v",
"status": "ready",
"customer_id": "ctm_01gywfmzk8038netxxbhk80vwe",
"address_id": "add_01gywfmzn2dwxry2rhry1b5gj4",
"business_id": null,
"custom_data": {
"utm_source": "crm",
"utm_medium": "email",
"utm_content": "closed-deal",
"integration_id": "AA-123"
},
"origin": "api",
"collection_mode": "automatic",
"subscription_id": null,
"invoice_id": null,
"invoice_number": null,
"billing_details": null,
"billing_period": null,
"currency_code": "GBP",
"discount_id": null,
"created_at": "2023-04-26T13:30:06.540543605Z",
"updated_at": "2023-04-26T13:30:06.540543605Z",
"billed_at": null,
"items": [
{
"price": {
"id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"description": "Monthly (per seat)",
"product_id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"billing_cycle": {
"interval": "month",
"frequency": 1
},
"trial_period": null,
"tax_mode": "account_setting",
"unit_price": {
"amount": "3000",
"currency_code": "GBP"
},
"unit_price_overrides": [
{
"country_codes": ["US"],
"unit_price": {
"amount": "4500",
"currency_code": "USD"
}
},
{
"country_codes": ["PL"],
"unit_price": {
"amount": "8000",
"currency_code": "PLN"
}
},
{
"country_codes": ["IN"],
"unit_price": {
"amount": "100500",
"currency_code": "INR"
}
},
{
"country_codes": ["UA"],
"unit_price": {
"amount": "40000",
"currency_code": "UAH"
}
},
{
"country_codes": ["NG"],
"unit_price": {
"amount": "1400",
"currency_code": "USD"
}
}
],
"quantity": {
"minimum": 10,
"maximum": 999
},
"status": "active"
},
"quantity": 10
}
],
"details": {
"tax_rates_used": [
{
"tax_rate": "0.2",
"totals": {
"subtotal": "30000",
"discount": "0",
"tax": "6000",
"total": "36000"
}
}
],
"totals": {
"subtotal": "30000",
"tax": "6000",
"discount": "0",
"total": "36000",
"fee": null,
"credit": "0",
"balance": "36000",
"earnings": null,
"currency_code": "GBP"
},
"payout_totals": null,
"line_items": [
{
"id": "txnitm_01gyyw3ja9rt8vh0n0wvyvn59k",
"price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"quantity": 10,
"totals": {
"subtotal": "30000",
"tax": "6000",
"discount": "0",
"total": "36000"
},
"product": {
"id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"name": "ChatApp Pro",
"description": "Everything in basic, plus access to a suite of powerful tools and features designed to take your team's productivity to the next level. Enjoy advanced integrations, improved admin controls, and cross-company chat.",
"tax_category": "standard",
"image_url": "https://twemoji.maxcdn.com/v/latest/72x72/2708.png",
"status": "active"
},
"tax_rate": "0.2",
"unit_totals": {
"subtotal": "3000",
"tax": "600",
"discount": "0",
"total": "3600"
}
}
]
},
"payments": [],
"checkout": {
"url": ""
}
},
"meta": {
"request_id": "f18ef701-42c7-476c-9083-34e36e59e920"
}
}

Update or remove custom data

You can update or remove custom data against a transaction or subscription using the API.

Send a PATCH request to the /transactions/{transaction_id} endpoint, including custom_data as a JSON object.

To remove custom data, set custom_data to null.

PATCH /transactions/{transaction_id}
Request
{
"custom_data": {
"integration_id": "BB-456"
}
}

Send a PATCH request to the /subscriptions/{subscription_id} endpoint, including custom_data as a JSON object. To remove custom data, set custom_data to null.

PATCH /subscriptions/{subscription_id}
Request
{
"custom_data": {
"integration_id": "BB-456"
}
}

Was this page helpful?