Sometimes a subscription should end on a set date: a free plan that runs until the end of a program, a sponsored seat for a fixed period, or a paid plan that shouldn't renew past a contract date. In Outseta you do this with the subscription's expiration date. Outseta doesn't bill the subscription past that date, and when the date arrives it ends the subscription.

This applies to subscriptions billed by Outseta. With Stripe Billing, Outseta doesn't run the renewals that end a subscription: set a cancellation date on the subscription in Stripe instead.

This guide covers:

  1. Giving a new subscription a fixed end date
  2. Setting or removing the end date of an existing subscription

The API reference has the same guide, with links to every field: Give a subscription a fixed end date.

Prerequisites

  • API Key and Secret from Settings > Integrations > API Keys
  • Account Uid of the customer
  • Plan Uid of the plan (for a new subscription)

ExpirationDate, not EndDate

A subscription has three dates that matter here:

  • ExpirationDate is the date you set to give the subscription a fixed end.
  • RenewalDate is calculated by Outseta from the plan's trial and the billing term. A value you send is ignored.
  • EndDate is set by Outseta when the subscription ends (on the expiration date, its EndDate becomes the ExpirationDate). Don't send it: a request with an EndDate is rejected with "The renewal date has to be null if the end date is set."

Method 1: New subscription

Add the subscription with the PUT First time subscription endpoint and include ExpirationDate. Leave out EndDate and RenewalDate.

const newSubscription = {
  Account: {
    Uid: '<account-uid>'
  },
  Plan: {
    Uid: '<plan-uid>'
  },
  BillingRenewalTerm: 1, // Monthly
  ExpirationDate: '2027-03-31T00:00:00Z'
};

const response = await fetch(
  `https://<your-domain>.outseta.com/api/v1/billing/subscriptions/firsttimesubscription`,
  {
    method: 'PUT',
    headers: {
      Authorization: `Outseta <api-key>:<secret-key>`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(newSubscription)
  }
);

Outseta keeps the ExpirationDate as you sent it. The subscription renews every billing term until then, and its first renewal date is never later than the expiration date. On a free plan with a monthly billing term, the subscription simply renews each month at no charge until the end date.

If you don't send an ExpirationDate, the plan decides, through its Set expiration date option (a number of months or a date). In the API this is Plan.ExpirationDate or Plan.ExpiresAfterMonths. An ExpiresAfterMonths of 0 means the plan never expires subscriptions; a value above 0 gives each new subscription an expiration date of its start date, plus the plan's trial days, plus that many months.

Method 2: Existing subscription

To set, change or remove the end date of a subscription that already exists, use the PUT Extend renewal endpoint on the account:

const response = await fetch(
  `https://<your-domain>.outseta.com/api/v1/crm/accounts/<account-uid>/extend-renewal`,
  {
    method: 'PUT',
    headers: {
      Authorization: `Outseta <api-key>:<secret-key>`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ ExpirationDate: '2027-03-31T00:00:00Z' })
  }
);
  • It changes the account's current subscription. The account must be subscribing, cancelling, trialing, cancelling its trial or past due, and it can't have a plan change scheduled to start later.
  • If the new expiration date is before the current renewal date, the renewal date moves to the expiration date.
  • Every request sets the expiration date. Without ExpirationDate, the existing expiration date is removed, except when ToDate is later than it: then the expiration date moves to ToDate. To remove the expiration date, send an empty body ({}). To change the renewal date (ToDate) and keep an expiration date, send both.
  • ToDate is checked with the time of day you send, while ExpirationDate is first set to the time of day of the subscription's start. Send ToDate with the time of day of the current RenewalDate, or a ToDate on the same day as the ExpirationDate may be rejected as later than it.

Why not change the subscription instead?

The PUT Change subscription endpoint isn't the right tool for an end date. With the same plan, billing term and quantity, it only changes add-ons and leaves the dates alone. A change to another plan creates a new subscription record. An upgrade, or any change while the account is in a trial, starts immediately. Any other change is scheduled for the current renewal date; add ?startImmediately=true to start it now. A free subscription added with First time subscription puts the account in the Trialing stage, so a change from it starts immediately.

Important API Notes

  • Authentication format: Outseta <api-key>:<secret-key>
  • Billing renewal terms: 1 = Monthly, 2 = Annual, 3 = Quarterly, 4 = One-time
  • Never expose API keys in client-side code