Skip to content

Events: subscriptions

Four keys: created_subscription, updated_subscription, deleted_subscription, and updated_change_choices (not in the catalogue). General configuration: Understanding a webhook delivery.

Every delivery carries the full subscription, with its plan, address and carrier.

FieldTypeNullableMeaning
idintegernointernal identifier
uuidstringnopublic identifier
planobjectyessee Plan object
addressobjectyessee customers/addresses page
transporterobjectyessee Carrier object
created_atdatenocreation
end_datedateyesend of the current period
engaged_datedateyesend of commitment
auto_pause_atdateyesscheduled automatic pause
start_datedateyessubscription start
activebooleannosubscription is active
pausedbooleannosubscription is paused
next_billingdateyesnext charge
update_transporter_atdateyesscheduled carrier change
relayobjectyespickup point
graceMonthsintegeryesremaining pause months
user_uuidstringnocustomer (cus_...)
user_idintegernocustomer id
emailstringnocustomer e-mail
revenuestringnorevenue generated (decimal point)
refundedstringnorefunded amount
customerRevenuestringnorevenue on the customer side
customerRefundstringnorefunded on the customer side
totalTransactionsSuccessintegernosuccessful transactions
subTransactionsSuccessintegernosuccessful transactions on the last order
countTransactionsintegernonumber of transactions of the last order
customization_productsarrayyescustomization
retry_link(always null)yesretry link
is_autobooleannotrue if an automatic pause starts within 5 days
intervalstringyesbilling period
interval_countintegeryesmultiplier
switch_plan_uuidstringyesscheduled plan switch
switch_plan_datedateyesswitch date
referrerstringyesacquisition source (referral, campaign)
display_intervalstringyesbilling period label
display_contentstringnoproducts (comma-separated)
external_fingerprintstringyesPrestaShop fingerprint
contentarraynosubscription products

The plan object follows the structure described below.

FieldTypeNullableMeaning
idintegernointernal identifier
uuidstringnopublic identifier
namestringnoplan name
short_namestringyesshort name
morestringyesdescription
imagestringyesimage URL
start_atdateyesavailability start
pricenumbernoprice excluding shipping
taxnumbernoVAT (0.2 = 20%)
intervalstringnobilling period
interval_countintegernomultiplier
shipped_countintegernoshipments per cycle
positionintegeryesdisplay order
engaged_intervalstringyescommitment length
engagedbooleannoplan with commitment
activebooleannoplan is active

The transporter object follows the same structure as in shipments, detailed under Carrier object.

Object sent: full subscription. Delay before sending: none.

  • Creation on the Ciklik site, or from an order (composable or PrestaShop).
  • Gift card activation: same mechanisms, hence an ordinary created_subscription (gift_activation_code is stored in the database but not exposed).
  • Subscription import by CSV, background task or command line: silent writes.

Always an empty array ([]).

If the shop has no existing marketing opt-in, a created_optin is sent as well (see customers/addresses/opt-ins page).

created_subscription
{
"id": 1,
"uuid": "sub_N8PxGUEdS2U7DP",
"plan": {
"id": 1,
"uuid": "boutique-exemple-box-mensuelle-1",
"name": "Box mensuelle",
"short_name": "Mensuelle",
"more": "Une sélection de trois thés chaque mois",
"image": "https://s3.eu-central-1.amazonaws.com/ciklik-media/plans/box-mensuelle.jpg",
"start_at": null,
"price": 29.9,
"tax": 0.2,
"interval": "month",
"interval_count": 1,
"shipped_count": 1,
"position": 1,
"engaged_interval": null,
"engaged": false,
"active": true
},
"address": {
"id": 1,
"user_id": 1,
"address": "12 rue des Lilas",
"address1": "Bâtiment B, 3e étage",
"postcode": "69003",
"city": "Lyon",
"phone": "+33612345678",
"first_name": "Claire",
"last_name": "Martin",
"region_id": 1,
"division": null,
"division_name": null,
"deletable": false,
"company_name": null,
"country": {
"id": 1,
"name": "France",
"alphaCode": "FR"
},
"external_id": 4821
},
"transporter": {
"id": 1,
"countries": [
{
"id": 1,
"name": "France"
}
],
"plan_blacklisted": [],
"name": "Colissimo domicile",
"description": "Livraison à domicile sous 48h",
"price": 4.9,
"gift": false,
"active": true,
"shipped_count": 1,
"type": "subs",
"relayOptions": null
},
"created_at": "2026-09-10T08:15:42.000000Z",
"end_date": "2026-10-09T00:00:00.000000Z",
"engaged_date": null,
"auto_pause_at": null,
"start_date": "2026-06-10T00:00:00.000000Z",
"active": true,
"paused": false,
"next_billing": "2026-10-10T08:15:42.000000Z",
"update_transporter_at": null,
"relay": null,
"graceMonths": null,
"user_uuid": "cus_Qx7hR3eaEowcv1DX",
"user_id": 1,
"email": "claire.martin@example.com",
"revenue": "0.00",
"refunded": "0.00",
"customerRevenue": "0.00",
"customerRefund": "0.00",
"totalTransactionsSuccess": 0,
"subTransactionsSuccess": 0,
"countTransactions": 1,
"customization_products": [
{
"id": 1,
"quantity": 1
}
],
"retry_link": null,
"is_auto": false,
"interval": "month",
"interval_count": 1,
"switch_plan_uuid": null,
"switch_plan_date": null,
"referrer": "newsletter",
"display_interval": "Monthly",
"display_content": "Box découverte",
"external_fingerprint": null,
"content": [
{
"external_id": "1042",
"quantity": 1,
"product_id": 1,
"subscription_id": 1
}
],
"changed": []
}

Object sent: full subscription, in its state at the time of sending (state re-read at the time of delivery). Delay before sending: none.

The most frequent event, with very different changed contents depending on the action:

  • Cancellation by the customer or by you (canceled_at set, active set to 0, next_billing/switch_plan_date cleared, plan_id if a plan switch was scheduled).
  • Reactivation of the subscription (active set to 1, next_billing recalculated, with cascade if charged immediately).
  • Restoration of a deleted subscription (deleted_at cleared, the only signal of the resurrection).
  • Anti-churn postponement (next_billing, end_date moved forward).
  • Pause by the team, with or without closing pending orders.
  • Change of address, carrier, variant, pickup point or customization, with cascade.
  • Update through the vendors API, PUT /subscriptions/{id}.
  • A scheduled plan switch, when it takes effect: the most costly trap on this page. plan_id, next_billing, switch_plan_date, switch_plan_uuid, auto_pause_at, engaged_date change in the database without any webhook.
  • Coupon applied to the next charge, CSV import, next_billing shifted by the team, interval/interval_count adjustment, bulk deactivation when a site is deleted, a plain history-log entry, PrestaShop technical writes.

An object {column: raw value}, dates in database format. Common fields: active, next_billing, end_date, canceled_at, plan_id, address_id, transporter_id, declinaison_id, customization_products, relay, grace_period, deleted_at, updated_at.

  • Cancellation: up to two updated_subscription (the second one if the subscription was paused). With order closing enabled: one updated_checkoutorder per pending order. Never a deleted_subscription.
  • Reactivation with immediate charge: followed by created_checkoutorder, created_checkouttransaction, often created_checkoutinvoice, timeline 0, 10, 10, 15 s (see orders/transactions/invoices page).
  • Pause with order closing: one updated_checkoutorder per order pending and being created, broader than cancellation.
  • Anti-churn postponement: followed by as many created_shippingbox as months postponed.
changed of updated_subscription
{
"changed": {
"next_billing": "2026-11-10 08:15:42",
"end_date": "2026-11-09 21:59:59",
"updated_at": "2026-09-10T08:15:42.000000Z"
}
}

Object sent: full subscription, even after deletion (the state is re-read at the time of delivery). Delay before sending: none.

  • Deletion through the vendors API, DELETE /subscriptions/{id}, accepted only on an inactive (cancelled) subscription, 422 otherwise.
  • Manual deletion by the team, only possible on an inactive subscription.
  • A cancellation: produces an updated_subscription, never this webhook; these are two distinct actions.
  • Restoring a deleted subscription: an updated_subscription (see above).

Always {"deleted": true}.

Before sending, every pending order is marked as failed (one updated_checkoutorder per order). Ciklik then notifies PrestaShop through another channel, which is not a merchant webhook.

changed of deleted_subscription
{
"changed": {
"deleted": true
}
}

updated_change_choices on request

Section titled “updated_change_choices ”

Object sent: full subscription, same structure as updated_subscription. Delay before sending: none.

Outside the 17 official keys: rejected by POST /webhooks (422, see Configuring webhooks through the API), can only be enabled by the Ciklik team, on request.

When customization_products changes on a subscription. Sent in addition to the usual updated_subscription, not instead of it.

  • Any other change on the subscription only produces an updated_subscription, without this key.
  • Cannot be enabled through the API, rejected with a 422.

A single field, customization_products: format trap, the value is not an object but a string containing encoded JSON, exactly as stored in the database.

customization_products is one of the fields tracked for the shipments cascade: one updated_shippingbox is sent per shipment scheduled since month M-2 (see the callout above).

changed of updated_change_choices
{
"changed": {
"customization_products": "[{\"id\":1,\"quantity\":2}]"
}
}