Subscription settings give you one place to control the global defaults that Reorder applies when new subscription operations begin. You can adjust trial lengths, dunning retry schedules, renewal behavior, and cancellation posture without redeploying your store.
Settings changes apply to future operations and newly created process state only. Existing active dunning cases, cancellation flows, and renewal cycles keep the configuration that was snapshotted when they were created.
Accessing subscription settings
In your Medusa Admin, navigate to Settings → Subscription Settings (/app/settings/subscription-settings). The page loads the current effective settings and lets you edit and save them in a single form.
The settings page is split into four sections:
- Trial — default trial period for new subscription operations
- Dunning — retry schedule and maximum attempt count for new dunning cases
- Renewals — default renewal behavior for newly started renewal cycles
- Cancellation defaults — default posture when a new cancellation flow opens
Configurable fields
| Field | Type | Default | Description |
|---|
default_trial_days | integer ≥ 0 | 0 | Number of trial days applied by default to new subscription operations. 0 means no default trial. |
dunning_retry_intervals | array of integers (minutes) | [1440, 4320, 10080] | Ordered retry schedule for newly created dunning cases, expressed in minutes. Must be strictly increasing with no duplicates. |
max_dunning_attempts | integer > 0 | 3 | Maximum number of retry attempts for newly created dunning flows. Must equal the number of intervals in dunning_retry_intervals. |
default_renewal_behavior | enum | process_immediately | Global default behavior when a new renewal operation begins. See renewal behavior values. |
default_cancellation_behavior | enum | recommend_retention_first | Global default posture when a new cancellation flow starts. See cancellation behavior values. |
Renewal behavior values
| Value | Meaning |
|---|
process_immediately | Treat new renewals as immediately processable from a global-settings perspective. Workflow-level validations and approval rules still apply. |
require_review_for_pending_changes | When a new renewal starts and there is reviewable change context (such as a pending plan update), default toward a review and approval path. |
Cancellation behavior values
| Value | Meaning |
|---|
recommend_retention_first | When a new cancellation flow opens, begin with retention-oriented handling — pause offers, discounts, or bonuses — before proceeding to cancellation. |
allow_direct_cancellation | When a new cancellation flow opens, allow a direct-cancellation path as the default posture. Cancellation validations still run. |
Persisted state and the is_persisted flag
Before you save settings for the first time, Reorder serves built-in fallback defaults. These defaults are not stored in the database — they are assembled at read time. Once you save settings for the first time, Reorder creates a persistent singleton record and uses it as the runtime source of truth.
The is_persisted field in the API response tells you which state you are in:
is_persisted | Meaning |
|---|
false | The response is built from fallback defaults. No settings have been saved yet. |
true | The response comes from the stored singleton. At least one save has occurred. |
The info panel at the top of the settings page shows the current version, updated_at, and updated_by values so you can see when the record was last changed and by whom.
The version field
Every successful save increments the version field by one. Version starts at 0 for fallback defaults and becomes 1 after the first save.
The version field is used for optimistic locking. When you submit a settings update through the API, you pass the expected_version you read to ensure your update is based on the latest state. If another update has occurred since your read, the API returns a 409 Conflict.
Updating settings via the Admin API
You can read and update subscription settings programmatically using the Admin API.
Get current settings
GET /admin/subscription-settings
This endpoint always returns a valid response. If no settings have been saved yet, it returns the fallback defaults with is_persisted: false. It never returns 404.
Example response (fallback defaults):
{
"subscription_settings": {
"settings_key": "global",
"default_trial_days": 0,
"dunning_retry_intervals": [1440, 4320, 10080],
"max_dunning_attempts": 3,
"default_renewal_behavior": "process_immediately",
"default_cancellation_behavior": "recommend_retention_first",
"version": 0,
"updated_by": null,
"updated_at": null,
"metadata": null,
"is_persisted": false
}
}
Update settings
POST /admin/subscription-settings
Send only the fields you want to change. Omitted fields keep their current effective values.
Request body:
{
"default_trial_days": 21,
"dunning_retry_intervals": [1440, 4320, 10080],
"max_dunning_attempts": 3,
"expected_version": 0
}
Pass expected_version: 0 for your first save. For subsequent saves, pass the version value returned by the most recent GET or POST response.
Example response (after first save):
{
"subscription_settings": {
"settings_key": "global",
"default_trial_days": 21,
"dunning_retry_intervals": [1440, 4320, 10080],
"max_dunning_attempts": 3,
"default_renewal_behavior": "process_immediately",
"default_cancellation_behavior": "recommend_retention_first",
"version": 1,
"updated_by": "user_01ABC",
"updated_at": "2026-04-03T14:00:00.000Z",
"metadata": {
"audit_log": [
{
"action": "update_settings",
"who": "user_01ABC",
"when": "2026-04-03T14:00:00.000Z",
"reason": "admin_save",
"previous_version": 0,
"next_version": 1,
"change_summary": [
{ "field": "default_trial_days", "from": 0, "to": 21 }
]
}
],
"last_update": {
"action": "update_settings",
"who": "user_01ABC",
"when": "2026-04-03T14:00:00.000Z",
"reason": "admin_save",
"previous_version": 0,
"next_version": 1,
"change_summary": [
{ "field": "default_trial_days", "from": 0, "to": 21 }
]
}
},
"is_persisted": true
}
}
Validation rules
The API enforces these rules on every update request:
default_trial_days must be >= 0
max_dunning_attempts must be > 0
dunning_retry_intervals must contain positive integers only
dunning_retry_intervals must be strictly increasing with no duplicates
max_dunning_attempts must equal the number of intervals in dunning_retry_intervals
default_renewal_behavior must be one of the supported enum values
default_cancellation_behavior must be one of the supported enum values
expected_version must be >= 0
A request that violates any of these rules returns 400 invalid_data. A version mismatch returns 409 Conflict.
Next steps
- Plugin setup — review the full plugin installation steps
- Dunning — understand how dunning cases consume these settings at create time
- Renewals — see how renewal behavior settings apply to new renewal cycles