Skip to Content

Update Charge Amount

POST/subscriptions/:id/update-charge-amount

Description

Change the recurring charge_amount on an active subscription. The Exodus API submits the on-chain SubscriptionManager.updateChargeAmount() transaction and pays gas.

The new amount takes effect immediately for the next cycle charge. The customer is not re-prompted to sign — the original subscribe signature authorized the contract for any amount up to cap_amount, and the merchant’s signature on this action proves the price change was authorized.

⚠️

new_amount must be <= cap_amount. The contract reverts with ChargeAmountExceedsCap otherwise — there is no way to raise the cap without the customer re-subscribing. Set a generous cap at intent creation if you anticipate price increases.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API keyyes
Content-Typeapplication/jsonyes
X-SignatureSignature from `signUpdateChargeAmount(...)`yes

Path Parameters

NameTypeDescriptionRequired
idstringThe subscription ID (e.g. `sub_abc123def456`).yes

Body Parameters

NameTypeDescriptionRequired
new_amountstringNew `charge_amount` in token's smallest unit. MUST equal the value passed to `signUpdateChargeAmount`. MUST be `> 0` and `<= cap_amount`.yes
charge_amount_update_noncenumberPre-increment `charge_amount_update_nonce` from the latest `GET /subscriptions/:id` read. MUST equal the value passed to `signUpdateChargeAmount`.yes

Producing the Signature

update-charge-amount.js
import { signUpdateChargeAmount } from '@exodus/checkout-signer'
 
const sub = await fetch('https://checkout.exodus.com/subscriptions/sub_abc123def456', {
  headers: { Authorization: `Bearer ${process.env.API_KEY}` },
}).then((r) => r.json())
 
const newAmount = '12990000' // $12.99 USDC (raised from $9.99)
 
const signature = signUpdateChargeAmount(
  sub.onchain_id,
  newAmount,
  sub.charge_amount_update_nonce,
  sub.subscription_manager_address,
  sub.chain,
  process.env.SIGNING_PRIVATE_KEY,
)
 
const response = await fetch(
  `https://checkout.exodus.com/subscriptions/${sub.id}/update-charge-amount`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.API_KEY}`,
      'Content-Type': 'application/json',
      'X-Signature': signature,
    },
    body: JSON.stringify({
      new_amount: newAmount,
      charge_amount_update_nonce: sub.charge_amount_update_nonce,
    }),
  },
)
 
const updatedSub = await response.json()
console.log(updatedSub.charge_amount) // "12990000"

Response

SUCCESSFUL RESPONSE
{
  "object": "subscription",
  "id": "sub_abc123def456",
  "status": "active",
  "onchain_id": "0x9f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a",
  "subscriber": "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE21",
  "chain": "eip155:1",
  "subscription_manager_address": "0xA1B2C3D4E5F6789012345678901234567890ABCD",
  "token_symbol": "USDC",
  "charge_amount": "12990000",
  "cap_amount": "120000000",
  "period_duration": 2592000,
  "charge_nonce": 3,
  "charge_amount_update_nonce": 1,
  "cancel_at_period_end": false,
  "last_charged_at": "2026-04-19T12:02:18Z",
  "next_charge_at": "2026-05-19T12:02:18Z",
  "metadata": { "external_plan_ref": "pro_monthly" },
  "created_at": "2026-02-19T12:02:18Z"
}

Errors

StatusCodeDescription
400subscription_cancelledSubscription is cancelled or cancelling.
400charge_amount_exceeds_capnew_amount > cap_amount.
400invalid_signatureSignature does not recover to your registered signing address.
400nonce_mismatchcharge_amount_update_nonce is stale. Re-fetch and re-sign.
404not_foundSubscription ID does not exist.
403forbiddenSubscription belongs to another merchant.

After the Update

The new amount is reflected on the next GET /subscriptions/:id read. Subsequent calls to POST /subscriptions/:id/charge MUST pass the new charge_amount. The on-chain contract enforces the new value as well as the original cap.

Start building

XO

Request Demo

Schedule a call with our team

Select a product
Arrow right

Start building
Grateful

Contact Us

We're here to help