Skip to content

Update a price

The prices.update operation: PATCH /api/v1/prices/{id} in the REST API and the prices_update tool in the MCP server.

PATCH/api/v1/prices/{id}

Changes a price's nickname, lookup key, metadata or active (false archives it, true reactivates it). Send only the fields to change; null clears an optional value; metadata replaces the whole map.

While no checkout session or payment has used the price (used: false), its tax behaviour and amounts can change as well: each of amount, customAmount, creditPack and recurring replaces the stored value. Once used, those are fixed (price_immutable): create a new price, move the lookup key to it with prices.move_lookup_key, and archive this one. The type and currency never change.

A lookup key held by another price isn't moved silently (lookup_key_taken); use prices.move_lookup_key.

At a glance

  • REST: PATCH /api/v1/prices/{id}
  • MCP tool: prices_update
  • Operation ID: prices.update
  • Scope: Brand
  • Permission: catalog:write
  • Risk tier: write
  • Dry run: Supported (send Ownrecord-Dry-Run: true)
  • Idempotency: Idempotency-Key optional
  • Modes: Test and live
  • Authentication: API key with the catalog:write scope
  • Since: M4

Request

Path parameters

FieldTypeDescription
idprice_… ID

Body

A JSON object (Content-Type: application/json):

FieldTypeRequiredDescription
nicknamestring or nullNo
lookupKeystring or nullNoSet a free lookup key, or null to remove it. To take one from another price, use prices.move_lookup_key.
metadataobjectNoYour own key-value pairs (at most 50 keys). On updates the whole set is replaced.
activebooleanNofalse archives the price, true reactivates it.
taxBehaviorone of inclusive, exclusiveNoUnused prices only.
amountobject or nullNoUnused prices only: the fixed amount; null removes it.
customAmountobject or nullNoUnused prices only: the custom amount range; null removes it.
creditPackobjectNoUnused credit packs only: the credit terms.
creditPack.creditsobjectNoThe pack's nominal credits; equals the amount (the default). Custom-amount packs have none. What the wallet receives follows the brand's credit basis (net by default).
creditPack.credits.amountstringYesInteger micros as a string (12500000 = 12.50).
creditPack.credits.currencystringYesISO 4217 currency code: the price's currency.
creditPack.bonusCreditsobjectNoPromo credits granted on top of the purchase.
creditPack.bonusCredits.amountstringYesInteger micros as a string (12500000 = 12.50).
creditPack.bonusCredits.currencystringYesISO 4217 currency code: the price's currency.
creditPack.expiresAfterDaysintegerNoDays until the credits expire (1–3650).
recurringobjectNoUnused recurring prices only: the billing period and scheme.
recurring.intervalone of day, week, month, yearYesThe billing period's unit.
recurring.intervalCountintegerNoPeriods per billing cycle (default 1).
recurring.usageTypeone of licensed, meteredNolicensed: the quantity is seats or units; metered: the quantity comes from usage events of metered.meter, billed in arrears.
recurring.billingSchemeone of per_unit, tieredNoper_unit: unitAmount × quantity; tiered: priced by tiers.
recurring.unitAmountobjectNoPer-unit prices: the price of one unit per period.
recurring.unitAmount.amountstringYesInteger micros as a string (12500000 = 12.50).
recurring.unitAmount.currencystringYesISO 4217 currency code: the price's currency.
recurring.tiersModeone of graduated, volumeNoTiered prices: graduated (each tier priced separately) or volume (all units at the reached tier).
recurring.tiersarray of objectNoTiered prices: the tiers, lowest first.
recurring.tiers[].upTointeger or "inf"YesThe last unit of the tier (inclusive); "inf" for the last tier.
recurring.tiers[].unitAmountMicrosstringYesPrice per unit in micros, as a string; sub-minor precision allowed (2500 = 0.0025).
recurring.tiers[].flatAmountobjectNoA fixed amount added once when the tier is reached.
recurring.tiers[].flatAmount.amountstringYesInteger micros as a string (12500000 = 12.50).
recurring.tiers[].flatAmount.currencystringYesISO 4217 currency code: the price's currency.
recurring.trialDaysintegerNoFree trial days for new subscriptions (1–730).
recurring.includedCreditsobjectNoCredits included every period (spec §17).
recurring.includedCredits.amountobjectYesCredits granted into the wallet each period.
recurring.includedCredits.amount.amountstringYesInteger micros as a string (12500000 = 12.50).
recurring.includedCredits.amount.currencystringYesISO 4217 currency code: the price's currency.
recurring.includedCredits.expiresAfterDaysintegerNo
recurring.meteredobjectNoMetered prices (usageType: metered): the meter and how its usage is aggregated and priced.
recurring.metered.meterstringYesThe meter usage events name, e.g. api.calls or payments.volume.
recurring.metered.aggregationone of sum, max, lastNoHow a period's usage is aggregated: sum of quantities, max (the largest), or last (the latest event's).
recurring.metered.pricingone of per_unit, percent_of_amountNoper_unit: the price's unitAmount or tiers per unit of usage; percent_of_amount: the quantity is an amount in micros of the price's currency, charged at ratePpm.
recurring.metered.ratePpmstringNopercent_of_amount only: the rate in parts per million (0.4% = "4000").
recurring.metered.includedQuantitystringNoFree usage per period, subtracted first (micros of the currency for percent_of_amount).
recurring.metered.minimumChargeobjectNoThe least the price charges per period, usage or not.
recurring.metered.minimumCharge.amountstringYesInteger micros as a string (12500000 = 12.50).
recurring.metered.minimumCharge.currencystringYesISO 4217 currency code: the price's currency.
recurring.metered.maximumChargeobjectNoThe most the price charges per period.
recurring.metered.maximumCharge.amountstringYesInteger micros as a string (12500000 = 12.50).
recurring.metered.maximumCharge.currencystringYesISO 4217 currency code: the price's currency.

Response

200 OK with a JSON object:

FieldTypeDescription
idprice_… ID
object"price"
brandIdbrd_… ID
livemodeboolean
productIdprod_… ID
nicknamestring or null
lookupKeystring or null
typeone of one_time, recurring, credit_pack
currencystring
taxBehaviorone of inclusive, exclusive
amountmoney or nullFixed one-time or credit-pack amount.
customAmountobject or nullThe range a buyer may choose from (custom-amount prices).
creditPackobject or null
recurringobject or null
activeboolean
usedbooleanA checkout session or payment referenced the price: what it charges can no longer change.
usedAtdate-time or null
metadataobject
createdAtdate-time
updatedAtdate-time

Examples

Rename a price

HTTP
PATCH /api/v1/prices/price_01m4tx5nj8emwbyf7y9vcf47y2
Authorization: Bearer or_test_…
Content-Type: application/json

{
  "nickname": "Pro monthly (2026)"
}

Response (200):

JSON
{
  "id": "price_01m4tx5nj8emwbyf7y9vcf47y2",
  "object": "price",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "productId": "prod_01m4tx5nj8emwbyf7y9vcf47y0",
  "nickname": "Pro monthly (2026)",
  "lookupKey": "pro_monthly",
  "type": "recurring",
  "currency": "EUR",
  "taxBehavior": "inclusive",
  "amount": null,
  "customAmount": null,
  "creditPack": null,
  "recurring": {
    "interval": "month",
    "intervalCount": 1,
    "usageType": "licensed",
    "billingScheme": "tiered",
    "unitAmount": null,
    "tiersMode": "graduated",
    "tiers": [
      {
        "upTo": 10,
        "unitAmountMicros": "12000000",
        "flatAmount": null
      },
      {
        "upTo": "inf",
        "unitAmountMicros": "9000000",
        "flatAmount": null
      }
    ],
    "trialDays": 14,
    "includedCredits": null,
    "metered": null
  },
  "active": true,
  "used": false,
  "usedAt": null,
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-14T09:30:00.000Z"
}

Errors

CodeHTTP statusWhenWhat to do
validation_failed400No field to change was sent, one is malformed, or the new terms break a rule.Fix the fields listed in details.issues and send the request again.
price_immutable409The price has been used and the request changes what it charges.Create a new price with the new terms, move the lookup key to it with prices.move_lookup_key, and archive this one.
meter_definition_conflict409New metered terms disagree with another metered price of the meter (aggregation, pricing or currency).Use the meter's existing aggregation and pricing (and, for percent of amount, its currency), or choose another meter key.
lookup_key_taken409Another price of the brand already has the lookup key.Move the key explicitly with prices.move_lookup_key (POST /prices/{id}/move_lookup_key), or choose another key.
price_archived409A lookup key was set on an archived price.Reactivate the price first (active: true), or use an active price.
resource_not_found404No price with this ID is visible to the request.Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
version_conflict409The price changed at the same time; retry.Fetch the object again and retry the change.
permission_denied403You can't change this brand's catalog.Ask an organization owner or admin for a role or scope that allows this action.

It can also return these common errors: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, scope_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.