Skip to content

Subscriptions

A Subscription represents a Customer’s subscription to a recurring SubscriptionPlan. Sangho automatically handles renewals, retries in case of payment failure, and email notifications.

Typical use cases: monthly SaaS subscription, access to a training platform, a recurring service plan with or without a trial period.

Automatic renewals

Sangho automatically charges the Customer at the end of each period via the saved payment method. If it fails, the Subscription moves to past_due and automatic retries are triggered. You receive a subscription.payment_failed webhook for each failed attempt.

Lifecycle

trialingactivepast_duepausedcanceled / unpaid / expired
StatusMeaningAvailable action
trialingTrial period in progress — no charge./cancel/, /pause/.
activeActive subscription — renewals ongoing./cancel/, /pause/.
past_dueRenewal failed — retries in progress./cancel/ or wait for the retry.
pausedManually suspended — no charge./resume/ to resume.
canceledCanceled — no future charges./reactivate/ if within the window.
unpaidAll retries have failed.Manual action required.
expiredReached its end (defined end date).Create a new Subscription.

Endpoints

MéthodeEndpointDescription
POST/subscriptions/Create a subscription
GET/subscriptions/List subscriptions
GET/subscriptions/{id}/Retrieve a subscription
PATCH/subscriptions/{id}/Update a subscription
POST/subscriptions/{id}/cancel/Cancel
POST/subscriptions/{id}/reactivate/Reactivate after cancellation
POST/subscriptions/{id}/pause/Suspend charges
POST/subscriptions/{id}/resume/Resume after suspension

Object schema

ResponseSubscription object
Full structure returned by all endpoints of this resource.
json
{
  "id": "sub_xxxxxxxxxxxx",
  "object": "subscription",
  "app": "app_xxxxxxxx",
  "customer": "cust_3Nx8mLKZ2eZvKYlo",
  "status": "active",
  "currency": "XAF",
  "unit_amount": 9900,
  "interval": "month",
  "interval_count": 1,
  "collection_method": "charge_automatically",
  "current_period_start": "2026-03-01T00:00:00Z",
  "current_period_end": "2026-04-01T00:00:00Z",
  "trial_start": null,
  "trial_end": null,
  "canceled_at": null,
  "cancel_at_period_end": false,
  "payment_method": "meth_xxxxxxxxxxxx",
  "metadata": {},
  "created_at": "2026-03-01T10:00:00Z",
  "updated_at": "2026-03-01T10:00:00Z"
}

Create a Subscription

Creates a recurring subscription for a Customer. If a trial_period_days is set, the Subscription starts in trialing status and the first charge is deferred.

POSTRequest body
customerRequis
stringcust_...

ID of the Customer to subscribe. The Customer must exist and have a valid email address to receive renewal notifications.

unit_amountRequis
integercents

Amount charged at each billing period, in cents.

If you use a SubscriptionPlan, pass the plan field instead — the amount will be inherited from the plan and you won’t need to specify it here.

intervalRequis
string

Unit of the billing period. Values: day, week, month, year.

interval_countOptionnel
integerdéfaut :1

Multiplier for the interval. For example, interval: “month” + interval_count: 3 = quarterly billing.

productOptionnel
stringprod_...

ID of the Product associated with this subscription. Allows the product’s name and image to be displayed on renewal invoices.

payment_methodOptionnel
stringmeth_...

ID of the payment method to charge at each renewal. If not provided, the Customer’s default payment method is used.

En savoir plus

The method must belong to the Customer and be active. For Mobile Money payments, the associated phone number must be valid and sufficiently funded at the time of renewal.

collection_methodOptionnel
stringdéfaut :charge_automatically

Payment collection mode. charge_automatically automatically charges the saved payment method. send_invoice generates an Invoice sent to the Customer at each renewal.

En savoir plus

send_invoice is recommended for B2B subscriptions where the customer prefers to pay by invoice. The Customer then receives an email with the payment link each period.

trial_period_daysOptionnel
integer

Length of the free trial period, in days, for this specific subscriber. Overrides the value set on the SubscriptionPlan.

En savoir plus

During the trial period, the Subscription is in trialing status and no charge is made. A subscription.trial_will_end webhook is sent 3 days before the trial ends to allow for proactive outreach.

cancel_at_period_endOptionnel
booleandéfaut :false

If true, the Subscription is automatically canceled at the end of the current period. No renewal will take place.

En savoir plus

Useful for “end of month” cancellations: access is maintained until the end of the paid period, then the Subscription moves to canceled with no additional charge.

metadataOptionnel
object

Free-form data — internal reference, original plan, acquisition channel, etc.

En savoir plus

The metadata is included in all webhooks related to this Subscription (subscription.created, subscription.canceled, subscription.payment_failed).

Create a subscription

bash
curl -X POST https://api.sangho.ga/v1/subscriptions/ \
  -H "Authorization: Bearer sk_prod_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "cust_3Nx8mLKZ2eZvKYlo",
    "unit_amount": 9900,
    "interval": "month",
    "payment_method": "meth_xxxxxxxxxxxx",
    "trial_period_days": 14,
    "metadata": { "plan_tier": "growth" }
  }'
Response201 Created
The Subscription is created. The status is trialing if a trial_period_days is set, active otherwise.
json
{
  "id": "sub_xxxxxxxxxxxx",
  "object": "subscription",
  "app": "app_xxxxxxxx",
  "customer": "cust_3Nx8mLKZ2eZvKYlo",
  "status": "trialing",
  "currency": "XAF",
  "unit_amount": 9900,
  "interval": "month",
  "interval_count": 1,
  "collection_method": "charge_automatically",
  "current_period_start": "2026-03-01T00:00:00Z",
  "current_period_end": "2026-04-01T00:00:00Z",
  "trial_start": "2026-03-01T00:00:00Z",
  "trial_end": "2026-03-15T00:00:00Z",
  "canceled_at": null,
  "cancel_at_period_end": false,
  "payment_method": "meth_xxxxxxxxxxxx",
  "metadata": { "plan_tier": "growth" },
  "created_at": "2026-03-01T10:00:00Z",
  "updated_at": "2026-03-01T10:00:00Z"
}

Manage the lifecycle

Cancel (/cancel/): ends the subscription. Pass cancel_at_period_end: true in the body to defer cancellation to the end of the current period — access is maintained until then.

Reactivate (/reactivate/): restores a recently canceled Subscription, provided the grace period hasn’t expired. The Subscription resumes in active status with the next renewal scheduled.

Suspend (/pause/): suspends charges without canceling the subscription. The Subscription moves to paused. Useful for customers on leave or facing temporary difficulty.

Resume (/resume/): resumes a suspended Subscription. The next charge is scheduled for the next normal period.

Immediate cancellation vs. end of period

Calling /cancel/ with no body cancels immediately. Passing { cancel_at_period_end: true } lets the subscriber access the service until the end of the paid period — the recommended behavior for a better customer experience.

Update a Subscription

Allows you to update the payment method, collection mode, or metadata of an active Subscription.

PATCHUpdate body (PATCH)
payment_methodOptionnel
stringmeth_...

New payment method for upcoming renewals. Must belong to the Customer.

collection_methodOptionnel
string

Change the collection mode: charge_automatically or send_invoice.

cancel_at_period_endOptionnel
boolean

Pass true to schedule a cancellation at the end of the period. Pass false to cancel a scheduled cancellation.

metadataOptionnel
object
Merged with existing metadata.

Cancel at the end of the period

bash
curl -X POST https://api.sangho.ga/v1/subscriptions/sub_xxx/cancel/ \
  -H "Authorization: Bearer sk_prod_xxxx" \
  -H "Content-Type: application/json" \
  -d '{ "cancel_at_period_end": true }'

Suspend / Resume

bash
# Suspend
curl -X POST https://api.sangho.ga/v1/subscriptions/sub_xxx/pause/ \
  -H "Authorization: Bearer sk_prod_xxxx"


# Resume
curl -X POST https://api.sangho.ga/v1/subscriptions/sub_xxx/resume/ \
  -H "Authorization: Bearer sk_prod_xxxx"
Response200 OK — Cancellation scheduled
The Subscription remains active until current_period_end, then automatically moves to canceled.
Pass cancel_at_period_end: false via PATCH to cancel a scheduled cancellation before it takes effect.
json
{
  "id": "sub_xxxxxxxxxxxx",
  "status": "active",
  "cancel_at_period_end": true,
  "current_period_end": "2026-04-01T00:00:00Z",
  "canceled_at": null,
  "updated_at": "2026-03-15T10:00:00Z"
}

Change the payment method

bash
curl -X PATCH https://api.sangho.ga/v1/subscriptions/sub_xxx/ \
  -H "Authorization: Bearer sk_prod_xxxx" \
  -H "Content-Type: application/json" \
  -d '{ "payment_method": "meth_yyyyyyyyyyyy" }'
Response200 OK — Subscription updated
The new payment method will be used starting with the next renewal.
json
{
  "id": "sub_xxxxxxxxxxxx",
  "status": "active",
  "payment_method": "meth_yyyyyyyyyyyy",
  "updated_at": "2026-03-20T14:00:00Z"
}