Skip to main content
The subscription settings endpoints manage the global configuration singleton used by the Reorder plugin at runtime. You can read the effective settings — which fall back to hardcoded defaults if no record has been persisted yet — and write a new or updated singleton through the dedicated workflow. All routes require an authenticated Medusa Admin user. The POST route uses optimistic locking via expected_version.
All routes require an authenticated Medusa Admin user. Unauthenticated requests return 401.

Field reference

FieldTypeDescription
settings_keystringAlways global in MVP.
default_trial_daysnumberDefault trial length in days. Must be >= 0.
dunning_retry_intervalsnumber[]Retry schedule in minutes. Must be strictly increasing positive integers.
max_dunning_attemptsnumberMaximum retry attempts. Must equal the number of intervals.
default_renewal_behaviorstringprocess_immediately or require_review_for_pending_changes.
default_cancellation_behaviorstringrecommend_retention_first or allow_direct_cancellation.
versionnumberMonotonic version for optimistic locking.
is_persistedbooleanfalse when the response uses fallback defaults; true when a stored record exists.

GET /admin/subscription-settings

Returns the effective settings payload. When no record has been saved yet the response uses hardcoded fallback defaults and is_persisted is false. This route never returns 404.

Response

subscription_settings
object
required
Fallback response example
{
  "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
  }
}
Persisted response example
{
  "subscription_settings": {
    "settings_key": "global",
    "default_trial_days": 21,
    "dunning_retry_intervals": [45, 180, 720],
    "max_dunning_attempts": 3,
    "default_renewal_behavior": "require_review_for_pending_changes",
    "default_cancellation_behavior": "allow_direct_cancellation",
    "version": 1,
    "updated_by": "user_01ABC",
    "updated_at": "2026-04-03T14:00:00.000Z",
    "metadata": {
      "audit_log": [],
      "last_update": null
    },
    "is_persisted": true
  }
}

POST /admin/subscription-settings

Persists a new or updated settings singleton through the dedicated workflow. The first successful POST creates the record. Omitted fields retain their current effective value.

Body parameters

default_trial_days
number
Default trial length in days. Must be >= 0.
dunning_retry_intervals
number[]
Retry intervals in minutes. Must be strictly increasing positive integers. Length must equal max_dunning_attempts.
max_dunning_attempts
number
Maximum retry attempts. Must be a positive integer equal to the number of intervals.
default_renewal_behavior
string
Global renewal policy. One of process_immediately or require_review_for_pending_changes.
default_cancellation_behavior
string
Global cancellation policy. One of recommend_retention_first or allow_direct_cancellation.
expected_version
number
Current version for optimistic locking. Use 0 on the first write.
reason
string
Optional reason for the update, recorded in the audit log.
Request example
{
  "default_trial_days": 21,
  "dunning_retry_intervals": [45, 180, 720],
  "max_dunning_attempts": 3,
  "default_renewal_behavior": "require_review_for_pending_changes",
  "default_cancellation_behavior": "allow_direct_cancellation",
  "expected_version": 0,
  "reason": "admin_save"
}

Response

Returns the updated subscription_settings object. The metadata.audit_log and metadata.last_update fields record the change summary.
Response example
{
  "subscription_settings": {
    "settings_key": "global",
    "default_trial_days": 21,
    "dunning_retry_intervals": [45, 180, 720],
    "max_dunning_attempts": 3,
    "default_renewal_behavior": "require_review_for_pending_changes",
    "default_cancellation_behavior": "allow_direct_cancellation",
    "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
  }
}

Errors

CodeErrorMeaning
400invalid_dataInvalid scalar ranges, invalid enum values, invalid retry interval list, or mismatched max_dunning_attempts
409conflictStale expected_version — optimistic locking mismatch
500unexpected_stateUnexpected workflow or persistence failure