subscriptions

Stable. Describes behaviour that is built and covered by tests in this repository.

API reference

GET /v1/subscriptions #

Subscriptions, newest first

Parameters

NameInTypeDescription
customerquerystringCustomer external id
page_sizequeryinteger
page_tokenquerystring

Responses

StatusMeaningBody
200OKListSubscriptionsResponse
404Error envelopeError
Example response
{
  "subscriptions": [
    {
      "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
      "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
      "customer_external_id": "string",
      "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
      "start_time": "2026-11-03T10:15:00Z",
      "end_time": null,
      "create_time": "2026-11-03T10:15:00Z",
      "state": "SUBSCRIPTION_STATE_TRIALING",
      "interval": "SUBSCRIPTION_INTERVAL_MONTH",
      "currency": "string",
      "trial_end_time": null,
      "cancel_at_period_end": false,
      "pause_time": null,
      "provider": "string",
      "provider_ref": "string",
      "owner": "payrudder",
      "plan_code": "string",
      "plan_version": 1,
      "fee_timing": "FEE_TIMING_ADVANCE",
      "scheduled_change": {
        "plan_code": "string",
        "plan_version": 1,
        "interval": "SUBSCRIPTION_INTERVAL_MONTH",
        "effective_time": "2026-11-03T10:15:00Z",
        "quantity": 1
      },
      "coupon_code": "string",
      "quantity": 1,
      "changed_from_id": "string"
    }
  ],
  "next_page_token": "string"
}
curl
curl -X GET https://YOUR-API-ADDRESS/v1/subscriptions \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

POST /v1/subscriptions #

Subscribe a customer to a plan version (at most one overlapping subscription per customer)

Request body

FieldTypeDescription
customer_external_id requiredstring
plan_code requiredstring
plan_versioninteger0 = latest
start_timestring · date-time
trial_daysintegerLeft out: the package version's own default trial. 0: no trial whatever the default is
intervalSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEAR
currencystringDefault is the customer's billing currency, then the tenant's
providerstringThe payment provider that sells it (for example paddle); default is the tenant's default account
coupon_codestringA coupon to redeem on the new subscription
quantityintegerSeats: the fixed fee is multiplied by it, usage prices are not. Default 1. Only for a subscription Payrudder runs and bills in advance
fee_timingFEE_TIMING_ADVANCE | FEE_TIMING_ARREARSDefault advance: the fixed fee is invoiced at the start of each period, usage at the close of the month. Arrears (monthly only) bills the fee with the month's usage. A provider that renews subscriptions itself bills the fee.
Example
{
  "customer_external_id": "string",
  "plan_code": "string"
}

Responses

StatusMeaningBody
201CreatedSubscription
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customer_external_id":"string","plan_code":"string"}'

GET /v1/subscriptions/{id} #

One subscription with its state

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Responses

StatusMeaningBody
200OKSubscription
404Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X GET https://YOUR-API-ADDRESS/v1/subscriptions/<id> \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

DELETE /v1/subscriptions/{id} #

End a subscription (now, or at end_time)

With credit_unused=true the fee paid in advance for the rest of the current period is credited to the customer's balance (for a subscription billed in advance that Payrudder runs, ended now, without a coupon). The response is always {subscription, credited_minor}; credited_minor is "0" when nothing was credited.

Parameters

NameInTypeDescription
id requiredpathstring · uuid
end_timequerystring · date-time
credit_unusedqueryboolean

Responses

StatusMeaningBody
200OKCancelSubscriptionResponse
404Error envelopeError
409Error envelopeError
Example response
{
  "subscription": {
    "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "customer_external_id": "string",
    "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "start_time": "2026-11-03T10:15:00Z",
    "end_time": null,
    "create_time": "2026-11-03T10:15:00Z",
    "state": "SUBSCRIPTION_STATE_TRIALING",
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "currency": "string",
    "trial_end_time": null,
    "cancel_at_period_end": false,
    "pause_time": null,
    "provider": "string",
    "provider_ref": "string",
    "owner": "payrudder",
    "plan_code": "string",
    "plan_version": 1,
    "fee_timing": "FEE_TIMING_ADVANCE",
    "scheduled_change": {
      "plan_code": "string",
      "plan_version": 1,
      "interval": "SUBSCRIPTION_INTERVAL_MONTH",
      "effective_time": "2026-11-03T10:15:00Z",
      "quantity": 1
    },
    "coupon_code": "string",
    "quantity": 1,
    "changed_from_id": "string"
  },
  "credited_minor": "string"
}
curl
curl -X DELETE https://YOUR-API-ADDRESS/v1/subscriptions/<id> \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

POST /v1/subscriptions/{id}/pause #

Stop the fixed fee until the subscription is resumed (usage is still billed)

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Responses

StatusMeaningBody
200OKSubscription
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions/<id>/pause \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

POST /v1/subscriptions/{id}/resume #

Resume a paused subscription

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Responses

StatusMeaningBody
200OKSubscription
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions/<id>/resume \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

POST /v1/subscriptions/{id}/cancel-at-period-end #

End the subscription at the end of its current billing period

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Responses

StatusMeaningBody
200OKSubscription
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions/<id>/cancel-at-period-end \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

DELETE /v1/subscriptions/{id}/cancel-at-period-end #

Withdraw a scheduled cancellation

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Responses

StatusMeaningBody
200OKSubscription
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X DELETE https://YOUR-API-ADDRESS/v1/subscriptions/<id>/cancel-at-period-end \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

POST /v1/subscriptions/{id}/change-plan #

Move the subscription to another plan version now, prorating the fixed fee

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Request body

FieldTypeDescription
plan_code requiredstring
plan_versioninteger0 = latest
change_timestring · date-timeDefault now
Example
{
  "plan_code": "string"
}

Responses

StatusMeaningBody
200OKChangePlanResponse
400Error envelopeError
404Error envelopeError
409Error envelopeError
Example response
{
  "subscription": {
    "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "customer_external_id": "string",
    "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "start_time": "2026-11-03T10:15:00Z",
    "end_time": null,
    "create_time": "2026-11-03T10:15:00Z",
    "state": "SUBSCRIPTION_STATE_TRIALING",
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "currency": "string",
    "trial_end_time": null,
    "cancel_at_period_end": false,
    "pause_time": null,
    "provider": "string",
    "provider_ref": "string",
    "owner": "payrudder",
    "plan_code": "string",
    "plan_version": 1,
    "fee_timing": "FEE_TIMING_ADVANCE",
    "scheduled_change": {
      "plan_code": "string",
      "plan_version": 1,
      "interval": "SUBSCRIPTION_INTERVAL_MONTH",
      "effective_time": "2026-11-03T10:15:00Z",
      "quantity": 1
    },
    "coupon_code": "string",
    "quantity": 1,
    "changed_from_id": "string"
  },
  "old_plan_fee_minor": "string",
  "new_plan_fee_minor": "string"
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions/<id>/change-plan \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"plan_code":"string"}'

POST /v1/subscriptions/{id}/change-preview #

What a change of plan or interval would cost, without making it

The same calculation as the change itself, so the preview is what is then billed. For subscriptions whose fee is invoiced in advance.

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Request body

FieldTypeDescription
plan_codestringEmpty keeps the plan (to change the interval only)
plan_versioninteger0 = latest
intervalSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEARDefault keeps the interval
timingCHANGE_TIMING_IMMEDIATELY | CHANGE_TIMING_PERIOD_ENDDefault depends on the direction of the change
prorationCHANGE_PRORATION_PRORATE | CHANGE_PRORATION_FULL | CHANGE_PRORATION_NONEDefault prorate. Prorate keeps the cycle within an interval; full starts a new cycle now; none moves no money now
change_timestring · date-timeDefault now; not in the future
quantityintegerThe new number of seats; 0 or absent keeps it. A change of seats alone is immediate and prorated in either direction unless timing says otherwise: the unused time of the old seats is credited and the new seats are charged for the rest of the period
Example
{}

Responses

StatusMeaningBody
200OKChangeQuote
400Error envelopeError
404Error envelopeError
409Error envelopeError
Example response
{
  "timing": "CHANGE_TIMING_IMMEDIATELY",
  "proration": "CHANGE_PRORATION_PRORATE",
  "effective_time": "2026-11-03T10:15:00Z",
  "period_start": "2026-11-03T10:15:00Z",
  "period_end": "2026-11-03T10:15:00Z",
  "credit_minor": "string",
  "charge_minor": "string",
  "net_minor": "string",
  "currency": "string",
  "next_renewal_time": "2026-11-03T10:15:00Z",
  "next_renewal_minor": "string",
  "plan_code": "string",
  "plan_version": 1,
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "quantity": 1
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions/<id>/change-preview \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

POST /v1/subscriptions/{id}/change #

Move a subscription to another plan version and/or interval, now or at the end of the paid period

An upgrade or monthly-to-yearly change is immediate and prorated; a downgrade or yearly-to-monthly change waits for the end of the period the customer has paid for (a scheduled change, shown on the subscription). A change of quantity alone is immediate and prorated, more seats or fewer. Whatever moves money is invoiced, or becomes a credit balance when the new plan costs less than the unused old time was worth. Answers 409 ABORTED if the fee of the current period has not been invoiced yet; try again in a moment.

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Request body

FieldTypeDescription
plan_codestringEmpty keeps the plan (to change the interval only)
plan_versioninteger0 = latest
intervalSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEARDefault keeps the interval
timingCHANGE_TIMING_IMMEDIATELY | CHANGE_TIMING_PERIOD_ENDDefault depends on the direction of the change
prorationCHANGE_PRORATION_PRORATE | CHANGE_PRORATION_FULL | CHANGE_PRORATION_NONEDefault prorate. Prorate keeps the cycle within an interval; full starts a new cycle now; none moves no money now
change_timestring · date-timeDefault now; not in the future
quantityintegerThe new number of seats; 0 or absent keeps it. A change of seats alone is immediate and prorated in either direction unless timing says otherwise: the unused time of the old seats is credited and the new seats are charged for the rest of the period
Example
{}

Responses

StatusMeaningBody
200OKChangeSubscriptionResponse
400Error envelopeError
404Error envelopeError
409Error envelopeError
Example response
{
  "subscription": {
    "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "customer_external_id": "string",
    "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
    "start_time": "2026-11-03T10:15:00Z",
    "end_time": null,
    "create_time": "2026-11-03T10:15:00Z",
    "state": "SUBSCRIPTION_STATE_TRIALING",
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "currency": "string",
    "trial_end_time": null,
    "cancel_at_period_end": false,
    "pause_time": null,
    "provider": "string",
    "provider_ref": "string",
    "owner": "payrudder",
    "plan_code": "string",
    "plan_version": 1,
    "fee_timing": "FEE_TIMING_ADVANCE",
    "scheduled_change": {
      "plan_code": "string",
      "plan_version": 1,
      "interval": "SUBSCRIPTION_INTERVAL_MONTH",
      "effective_time": "2026-11-03T10:15:00Z",
      "quantity": 1
    },
    "coupon_code": "string",
    "quantity": 1,
    "changed_from_id": "string"
  },
  "quote": {
    "timing": "CHANGE_TIMING_IMMEDIATELY",
    "proration": "CHANGE_PRORATION_PRORATE",
    "effective_time": "2026-11-03T10:15:00Z",
    "period_start": "2026-11-03T10:15:00Z",
    "period_end": "2026-11-03T10:15:00Z",
    "credit_minor": "string",
    "charge_minor": "string",
    "net_minor": "string",
    "currency": "string",
    "next_renewal_time": "2026-11-03T10:15:00Z",
    "next_renewal_minor": "string",
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "quantity": 1
  },
  "scheduled": false
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions/<id>/change \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

POST /v1/subscriptions/{id}/coupon #

Redeem a coupon on a subscription that has none

A coupon takes something off a fixed fee Payrudder invoices in advance. A subscription a provider renews uses a discount at the provider instead.

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Request body

FieldTypeDescription
code requiredstring
Example
{
  "code": "string"
}

Responses

StatusMeaningBody
200OKSubscription
400Error envelopeError
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X POST https://YOUR-API-ADDRESS/v1/subscriptions/<id>/coupon \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"string"}'

DELETE /v1/subscriptions/{id}/coupon #

Take the coupon off a subscription (the redemption is not given back)

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Responses

StatusMeaningBody
200OKSubscription
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X DELETE https://YOUR-API-ADDRESS/v1/subscriptions/<id>/coupon \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

DELETE /v1/subscriptions/{id}/scheduled-change #

Withdraw the change waiting for the end of the period

Parameters

NameInTypeDescription
id requiredpathstring · uuid

Responses

StatusMeaningBody
200OKSubscription
404Error envelopeError
409Error envelopeError
Example response
{
  "id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "customer_external_id": "string",
  "plan_version_id": "0192f0b4-6f6e-7c3a-9a3e-6a1f2b3c4d5e",
  "start_time": "2026-11-03T10:15:00Z",
  "end_time": null,
  "create_time": "2026-11-03T10:15:00Z",
  "state": "SUBSCRIPTION_STATE_TRIALING",
  "interval": "SUBSCRIPTION_INTERVAL_MONTH",
  "currency": "string",
  "trial_end_time": null,
  "cancel_at_period_end": false,
  "pause_time": null,
  "provider": "string",
  "provider_ref": "string",
  "owner": "payrudder",
  "plan_code": "string",
  "plan_version": 1,
  "fee_timing": "FEE_TIMING_ADVANCE",
  "scheduled_change": {
    "plan_code": "string",
    "plan_version": 1,
    "interval": "SUBSCRIPTION_INTERVAL_MONTH",
    "effective_time": "2026-11-03T10:15:00Z",
    "quantity": 1
  },
  "coupon_code": "string",
  "quantity": 1,
  "changed_from_id": "string"
}
curl
curl -X DELETE https://YOUR-API-ADDRESS/v1/subscriptions/<id>/scheduled-change \
  -H "Authorization: Bearer $PAYRUDDER_API_KEY"

Models

ApplyCouponRequest

FieldTypeDescription
code requiredstring

CancelSubscriptionResponse

FieldTypeDescription
subscription requiredSubscription
credited_minor requiredstring · int64Minor units of the subscription's currency credited to the customer; "0" unless credit_unused credited something

ChangePlanRequest

FieldTypeDescription
plan_code requiredstring
plan_versioninteger0 = latest
change_timestring · date-timeDefault now

ChangePlanResponse

FieldTypeDescription
subscription requiredany
old_plan_fee_minor requiredstring · int64The old plan's share of the current month's fixed fee, up to change_time (informational; billing recomputes it)
new_plan_fee_minor requiredstring · int64The new plan's share of the current month's fixed fee, from change_time (informational; billing recomputes it)

ChangeQuote

FieldTypeDescription
timing requiredCHANGE_TIMING_IMMEDIATELY | CHANGE_TIMING_PERIOD_END
proration requiredCHANGE_PRORATION_PRORATE | CHANGE_PRORATION_FULL | CHANGE_PRORATION_NONE
effective_time requiredstring · date-time
period_start requiredstring · date-time
period_end requiredstring · date-time
credit_minor requiredstring · int64The unused, prepaid part of the old fee
charge_minor requiredstringWhat the new plan costs from the change, format: int64
net_minor requiredstring · int64charge - credit: positive is invoiced, negative becomes a credit balance
currency requiredstring
next_renewal_time requiredstring · date-time
next_renewal_minor requiredstring · int64
plan_code requiredstring
plan_version requiredinteger
interval requiredSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEAR
quantity requiredintegerThe seats after the change

ChangeRequest

FieldTypeDescription
plan_codestringEmpty keeps the plan (to change the interval only)
plan_versioninteger0 = latest
intervalSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEARDefault keeps the interval
timingCHANGE_TIMING_IMMEDIATELY | CHANGE_TIMING_PERIOD_ENDDefault depends on the direction of the change
prorationCHANGE_PRORATION_PRORATE | CHANGE_PRORATION_FULL | CHANGE_PRORATION_NONEDefault prorate. Prorate keeps the cycle within an interval; full starts a new cycle now; none moves no money now
change_timestring · date-timeDefault now; not in the future
quantityintegerThe new number of seats; 0 or absent keeps it. A change of seats alone is immediate and prorated in either direction unless timing says otherwise: the unused time of the old seats is credited and the new seats are charged for the rest of the period

ChangeSubscriptionResponse

FieldTypeDescription
subscription requiredany
quote requiredany
scheduled requiredbooleanTrue when the change waits for the end of the period

CreateSubscriptionRequest

FieldTypeDescription
customer_external_id requiredstring
plan_code requiredstring
plan_versioninteger0 = latest
start_timestring · date-time
trial_daysintegerLeft out: the package version's own default trial. 0: no trial whatever the default is
intervalSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEAR
currencystringDefault is the customer's billing currency, then the tenant's
providerstringThe payment provider that sells it (for example paddle); default is the tenant's default account
coupon_codestringA coupon to redeem on the new subscription
quantityintegerSeats: the fixed fee is multiplied by it, usage prices are not. Default 1. Only for a subscription Payrudder runs and bills in advance
fee_timingFEE_TIMING_ADVANCE | FEE_TIMING_ARREARSDefault advance: the fixed fee is invoiced at the start of each period, usage at the close of the month. Arrears (monthly only) bills the fee with the month's usage. A provider that renews subscriptions itself bills the fee.

Error

FieldTypeDescription
error requiredobject

ListSubscriptionsResponse

FieldTypeDescription
subscriptions requiredarray of Subscription
next_page_token requiredstring

ScheduledChange

FieldTypeDescription
plan_code requiredstring
plan_version requiredinteger
interval requiredSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEAR
effective_time requiredstring · date-time
quantity requiredintegerThe seats the subscription has from then

Subscription

FieldTypeDescription
id requiredstring · uuid
customer_id requiredstring · uuid
customer_external_id requiredstring
plan_version_id requiredstring · uuid
start_time requiredstring · date-time
end_time requiredstring,null · date-time
create_time requiredstring · date-time
state requiredSUBSCRIPTION_STATE_TRIALING | SUBSCRIPTION_STATE_ACTIVE | SUBSCRIPTION_STATE_PAST_DUE | SUBSCRIPTION_STATE_PAUSED | SUBSCRIPTION_STATE_CANCELLED
interval requiredSUBSCRIPTION_INTERVAL_MONTH | SUBSCRIPTION_INTERVAL_YEAR
currency requiredstring
trial_end_time requiredstring,null · date-time
cancel_at_period_end requiredboolean
pause_time requiredstring,null · date-time
provider requiredstring
provider_ref requiredstringThe provider's id of the subscription, once it is linked
owner requiredpayrudder | providerWho renews it and retries failed renewals; a provider-owned subscription is changed at the provider
plan_code requiredstring
plan_version requiredinteger
fee_timing requiredFEE_TIMING_ADVANCE | FEE_TIMING_ARREARS
scheduled_change requiredany
coupon_code requiredstring
quantity requiredintegerSeats: a plain multiplier of the plan's fixed fee, 1 unless set
changed_from_id requiredstring