Vatly
Api Reference

Subscriptions

On this page, we'll dive into the different subscription endpoints you can use to manage subscriptions programmatically.

The Subscription API Resource

The subscription model contains all the information about recurring billing relationships with customers.

Properties

NameTypeDescription
idstringUnique identifier for the subscription (starts with subscription_).
resourcestringThe resource type. Always subscription.
customerIdstringID of the customer who owns this subscription.
subscriptionPlanIdstringID of the subscription plan this subscription is based on (starts with subscription_plan_).
testmodebooleanWhether this resource is in test mode.
namestringThe name for the subscription (from the plan).
descriptionstringThe description for the subscription.
billingAddressobjectThe customer billing address for the subscription. Includes fullName, companyName, taxId, streetAndNumber, streetAdditional, city, region, postalCode, and country.
basePriceMoneyThe base price per billing cycle before taxes. A Money object with value (decimal string) and currency (ISO 4217 code).
quantityintegerThe quantity for the subscription (e.g., number of seats).
intervalstringThe billing interval. Can be day, week, month, or year.
intervalCountintegerThe interval count, e.g., "3" for charging every 3 months.
statusstringThe status for the subscription. Can be created, trial, active, canceled, on_grace_period, or paused.
cancellationReasonstring | nullWhy the subscription was canceled. Can be payment_failure (payment recovery was exhausted after failed renewals), merchant_request (the merchant canceled the subscription), or customer_request (the customer canceled from the self-service portal). Null unless a cancellation has been requested.
mandateobject | nullThe payment method (mandate) on file. Contains method (e.g. card, sepa_debit, paypal, bacs_debit) and maskedIdentifier (e.g. the last 4 digits). Null if no mandate is set.
startedAtstring | nullWhen the subscription started (ISO 8601 format).
endedAtstring | nullWhen the subscription actually ended (ISO 8601 format). Stays null during a cancellation grace period — it is only set once the subscription has fully ended.
canceledAtstring | nullWhen the subscription was canceled (ISO 8601 format). Set while in on_grace_period, and cleared again if the subscription is resumed. Null if not canceled.
renewedAtstring | nullWhen the subscription was last renewed (ISO 8601 format).
renewedUntilstring | nullCurrent billing period end date (ISO 8601 format).
nextRenewalAtstring | nullWhen the next renewal will be attempted (ISO 8601 format). Null if subscription is canceled or ended.
trialUntilstring | nullWhen the trial period ends (ISO 8601 format). Null if not in trial or trial has ended.
scheduledUpdateobject | nullThe target values for a plan/price/quantity change scheduled to take effect at the subscription's next billing cycle, set by an update with applyImmediately: false. The rest of the resource reflects the subscription's current state; scheduledUpdate is what it will become. Contains subscriptionPlanId, name, description, basePrice, quantity, interval, intervalCount, and effectiveAt (the next renewal date when the change applies, or null if there is no scheduled renewal). Null when nothing is pending. This is the authoritative way to reconcile a pending change — always present on the resource, so you don't need to rely on the subscription.update_scheduled webhook. Cleared when the change is applied at renewal, and when it is discarded because the subscription was canceled before that renewal.
linksobjectHATEOAS links to related resources. Contains self and customer links.

List all subscriptions

GET /v1/subscriptions

This endpoint allows you to retrieve a paginated list of all subscriptions across your account.

Optional attributes

NameTypeDescription
limitintegerThe number of subscriptions to return (default: 10, max: 100).
startingAfterstringA cursor for use in pagination. Returns results after this subscription ID.
endingBeforestringA cursor for use in pagination. Returns results before this subscription ID.
curl -G https://api.vatly.com/v1/subscriptions \
  -H "Authorization: Bearer live_your_api_key_here" \
  -d limit=10

Get a subscription

GET /v1/subscriptions/:id

This endpoint allows you to retrieve a specific subscription by its ID.

Parameters

NameTypeDescription
subscriptionIdstringThe unique identifier of the subscription.
curl https://api.vatly.com/v1/subscriptions/subscription_Lp3mNvBxKw7RjTgYcZaE \
  -H "Authorization: Bearer live_your_api_key_here"

List customer subscriptions

GET /v1/customers/:customerId/subscriptions

This endpoint allows you to retrieve a paginated list of all subscriptions for a specific customer.

Parameters

NameTypeDescription
customerIdstringThe unique identifier of the customer.
limitintegerThe number of subscriptions to return (default: 10, max: 100).
startingAfterstringA cursor for use in pagination. Returns results after this subscription ID.
endingBeforestringA cursor for use in pagination. Returns results before this subscription ID.
curl -G https://api.vatly.com/v1/customers/customer_Lp3mNvBxKw7RjTgYcZaE/subscriptions \
  -H "Authorization: Bearer live_your_api_key_here" \
  -d limit=10

Get a customer subscription

GET /v1/customers/:customerId/subscriptions/:subscriptionId

This endpoint allows you to retrieve a specific subscription for a specific customer.

Parameters

NameTypeDescription
customerIdstringThe unique identifier of the customer.
subscriptionIdstringThe unique identifier of the subscription.
curl https://api.vatly.com/v1/customers/customer_Lp3mNvBxKw7RjTgYcZaE/subscriptions/subscription_Lp3mNvBxKw7RjTgYcZaE \
  -H "Authorization: Bearer live_your_api_key_here"

Update a subscription

PATCH /v1/subscriptions/:id

This endpoint allows you to update a subscription. You can change the plan, quantity, or recurring price, and control proration and timing.

Optional attributes

At least one of subscriptionPlanId, quantity, or price must be provided.

NameTypeDescription
subscriptionPlanIdstringThe ID of the subscription plan to update to (starts with subscription_plan_). Must match the testmode of the current subscription.
quantityintegerThe new total quantity for the subscription (e.g. number of seats). This sets the quantity to the given value — it is not added to the current quantity. Must be at least 1.
priceobjectSet a new recurring price while keeping the current plan. A Money object with value (decimal string) and currency (EUR or USD); the currency must match the subscription's own currency. Sent alongside subscriptionPlanId, it overrides the new plan's default price.
proratebooleanWhether to prorate charges for the partial billing period. If true, the customer is credited for unused time on the old plan and charged for remaining time on the new plan. Default: true.
applyImmediatelybooleanWhether to apply changes immediately or at the end of the current billing period. When true, changes take effect immediately (with proration if enabled). When false, the change is scheduled for the end of the current period and surfaced on the subscription's scheduledUpdate. Default: false.
invoiceImmediatelybooleanWhether to generate and charge an invoice immediately for proration. Only applies when applyImmediately and prorate are both true. When false (the default), the proration delta is parked on the current cycle and billed as a line on the next renewal invoice — the customer gets one invoice and one payment covering both. If the subscription is canceled before that renewal, the parked amount is waived, so a customer is never charged at the moment they cancel. Set this to true on yearly and other long-interval plans, where the deferred delta may not be billed for many months and is waived entirely if the customer cancels in between. Default: false.
anchordateSet the billing anchor to a specific calendar date (YYYY-MM-DD, interpreted in UTC); the billing cycle is recalculated around it. Cannot be combined with resetAnchor.
resetAnchorbooleanReset the billing anchor to "now" — the moment the update is processed becomes the new cycle anchor and future renewals align to it. Cannot be combined with anchor. Default: false.
trialUntilstringExtend or set a trial period until this date (ISO 8601 format). Cannot be combined with anchor.

Scheduling and proration behavior:

  • With applyImmediately: false (the default), the change is scheduled for the next billing cycle and returned on the subscription's scheduledUpdate. Scheduled updates are applied at renewal — they are no longer silently discarded — and are cleared only if the subscription is canceled before that renewal.
  • A subscription whose status is on_grace_period has no next billing period. Scheduling an update for it returns 422; resume the subscription first, or set applyImmediately: true to apply the change to the remaining period.
  • An immediate update on an on_grace_period subscription can change the plan, price, or quantity for the remaining period, but not when that period ends — anchor, resetAnchor, and switching to a plan with a different interval each return 422, because each would move the already-communicated end date.
  • When invoiceImmediately is false, the proration delta is parked on the current cycle and billed on the next renewal invoice. If the subscription is canceled before that renewal, the parked charge is waived.
curl -X PATCH https://api.vatly.com/v1/subscriptions/subscription_Lp3mNvBxKw7RjTgYcZaE \
  -H "Authorization: Bearer live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriptionPlanId": "subscription_plan_Wt5mNvBxKw7YcZaEjLhR",
    "prorate": true,
    "applyImmediately": true
  }'

POST /v1/subscriptions/:id/billing-update-link

Creates a signed link that the customer can use to update the billing details for this subscription — billing address, VAT number, and company name — via a hosted flow.

Required attributes

NameTypeDescription
redirectUrlSuccessstringURL to redirect after successful billing update.
redirectUrlCanceledstringURL to redirect if customer cancels the update.

Optional attributes

NameTypeDescription
billingAddressobjectPre-fill billing address fields. Customer can modify these values in the hosted form.
curl -X POST https://api.vatly.com/v1/subscriptions/subscription_Lp3mNvBxKw7RjTgYcZaE/billing-update-link \
  -H "Authorization: Bearer live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "redirectUrlSuccess": "https://example.com/billing-updated",
    "redirectUrlCanceled": "https://example.com/account/billing",
    "billingAddress": {
      "companyName": "Acme Corp",
      "taxId": "DE123456789"
    }
  }'

Cancel a subscription

DELETE /v1/subscriptions/:id

This endpoint allows you to cancel a subscription. By default, the subscription will remain active until the end of the current billing period (grace period), after which it will be fully canceled. Set immediately=true to cancel immediately.

During the grace period the subscription's status is on_grace_period and canceledAt is set, while endedAt stays null. A grace-period cancellation can still be reversed with Resume a subscription until the period lapses. A subscription canceled with immediately=true (status canceled) cannot be reactivated — create a new subscription instead.

Optional query parameters

NameTypeDescription
immediatelybooleanCancel immediately instead of at period end. Default: false.
curl -X DELETE https://api.vatly.com/v1/subscriptions/subscription_Lp3mNvBxKw7RjTgYcZaE \
  -H "Authorization: Bearer live_your_api_key_here"

Returns 204 No Content on success.


Resume a subscription

POST /v1/subscriptions/:id/resume

Resumes a subscription that was canceled with a grace period, while it is still within that period.

When this works:

  • The subscription's status is on_grace_period.
  • endedAt stays null throughout the grace period — resumability is keyed off status, not endedAt.

Result:

  • Status returns to active.
  • The existing billing cycle and renewal schedule are preserved (no new charge fires immediately) and the original payment mandate remains in effect.
  • canceledAt is cleared and a subscription.resumed webhook is delivered.
  • The refreshed subscription is returned in the response body.

When this does not work (returns 422):

  • The subscription was canceled immediately (status is canceled).
  • The grace period has already lapsed (status is now canceled and endedAt is set).
  • The subscription is already active (the no-op is rejected for clarity, not silently ignored).

In all of those cases, create a new subscription instead.

Parameters

NameTypeDescription
idstringThe unique identifier of the subscription.
curl -X POST https://api.vatly.com/v1/subscriptions/subscription_Lp3mNvBxKw7RjTgYcZaE/resume \
  -H "Authorization: Bearer live_your_api_key_here"
Copyright © 2026