---
title: "Events: subscriptions"
description: "When subscription webhooks are sent (creation, update, deletion, choices), what they contain and the cascading effects they trigger."
url: https://www.ciklik.academy/en/webhooks/evenements-abonnements/
lang: en
lastUpdated: 2026-10-23
---

# Events: subscriptions

> Box and PrestaShop
>
> This page applies to both box stores and PrestaShop stores.

Four keys: `created_subscription`, `updated_subscription`, `deleted_subscription`, and `updated_change_choices` (not in the catalogue). General configuration: [Understanding a webhook delivery](https://www.ciklik.academy/en/webhooks/comprendre-un-envoi-de-webhook/).

## Subscription object

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

| Field                      | Type          | Nullable | Meaning                                                                                                    |
| -------------------------- | ------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `id`                       | integer       | no       | internal identifier                                                                                        |
| `uuid`                     | string        | no       | public identifier                                                                                          |
| `plan`                     | object        | yes      | see [Plan object](#plan-object)                                                                            |
| `address`                  | object        | yes      | see [customers/addresses page](https://www.ciklik.academy/en/webhooks/evenements-clients-adresses-optins/) |
| `transporter`              | object        | yes      | see [Carrier object](https://www.ciklik.academy/en/webhooks/evenements-expeditions/#carrier-object)        |
| `created_at`               | date          | no       | creation                                                                                                   |
| `end_date`                 | date          | yes      | end of the current period                                                                                  |
| `engaged_date`             | date          | yes      | end of commitment                                                                                          |
| `auto_pause_at`            | date          | yes      | scheduled automatic pause                                                                                  |
| `start_date`               | date          | yes      | subscription start                                                                                         |
| `active`                   | boolean       | no       | subscription is active                                                                                     |
| `paused`                   | boolean       | no       | subscription is paused                                                                                     |
| `next_billing`             | date          | yes      | next charge                                                                                                |
| `update_transporter_at`    | date          | yes      | scheduled carrier change                                                                                   |
| `relay`                    | object        | yes      | pickup point                                                                                               |
| `graceMonths`              | integer       | yes      | remaining pause months                                                                                     |
| `user_uuid`                | string        | no       | customer (`cus_...`)                                                                                       |
| `user_id`                  | integer       | no       | customer id                                                                                                |
| `email`                    | string        | no       | customer e-mail                                                                                            |
| `revenue`                  | string        | no       | revenue generated (decimal point)                                                                          |
| `refunded`                 | string        | no       | refunded amount                                                                                            |
| `customerRevenue`          | string        | no       | revenue on the customer side                                                                               |
| `customerRefund`           | string        | no       | refunded on the customer side                                                                              |
| `totalTransactionsSuccess` | integer       | no       | successful transactions                                                                                    |
| `subTransactionsSuccess`   | integer       | no       | successful transactions on the last order                                                                  |
| `countTransactions`        | integer       | no       | number of transactions of the last order                                                                   |
| `customization_products`   | array         | yes      | customization                                                                                              |
| `retry_link`               | (always null) | yes      | retry link                                                                                                 |
| `is_auto`                  | boolean       | no       | true if an automatic pause starts within 5 days                                                            |
| `interval`                 | string        | yes      | billing period                                                                                             |
| `interval_count`           | integer       | yes      | multiplier                                                                                                 |
| `switch_plan_uuid`         | string        | yes      | scheduled plan switch                                                                                      |
| `switch_plan_date`         | date          | yes      | switch date                                                                                                |
| `referrer`                 | string        | yes      | acquisition source (referral, campaign)                                                                    |
| `display_interval`         | string        | yes      | billing period label                                                                                       |
| `display_content`          | string        | no       | products (comma-separated)                                                                                 |
| `external_fingerprint`     | string        | yes      | PrestaShop fingerprint                                                                                     |
| `content`                  | array         | no       | subscription products                                                                                      |

## Plan object

The `plan` object follows the structure described below.

| Field              | Type    | Nullable | Meaning                  |
| ------------------ | ------- | -------- | ------------------------ |
| `id`               | integer | no       | internal identifier      |
| `uuid`             | string  | no       | public identifier        |
| `name`             | string  | no       | plan name                |
| `short_name`       | string  | yes      | short name               |
| `more`             | string  | yes      | description              |
| `image`            | string  | yes      | image URL                |
| `start_at`         | date    | yes      | availability start       |
| `price`            | number  | no       | price excluding shipping |
| `tax`              | number  | no       | VAT (`0.2` = 20%)        |
| `interval`         | string  | no       | billing period           |
| `interval_count`   | integer | no       | multiplier               |
| `shipped_count`    | integer | no       | shipments per cycle      |
| `position`         | integer | yes      | display order            |
| `engaged_interval` | string  | yes      | commitment length        |
| `engaged`          | boolean | no       | plan with commitment     |
| `active`           | boolean | no       | plan is active           |

The `transporter` object follows the same structure as in shipments, detailed under [Carrier object](https://www.ciklik.academy/en/webhooks/evenements-expeditions/#carrier-object).

## `created_subscription`

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

### When it is sent

- 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).

### When it is not sent

- Subscription import by CSV, background task or command line: silent writes.

### What changed contains

Always an empty array (`[]`).

### Cascading effects

If the shop has no existing marketing opt-in, a `created_optin` is sent as well (see [customers/addresses/opt-ins page](https://www.ciklik.academy/en/webhooks/evenements-clients-adresses-optins/)).

### Example

```json
{
    "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": []
}
```

## `updated_subscription`

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

### When it is sent

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).
- Cancellation from the back office (**Cancel the subscription** action on the subscription record), with or without the **Close pending orders** option.
- Change of address, carrier, variant, pickup point or customization, with cascade.
- Update through the vendors API, `PUT /subscriptions/{id}`.

### When it is not sent

- **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.

### What changed contains

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`.

### Cascading effects

- **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](https://www.ciklik.academy/en/webhooks/evenements-commandes-transactions-factures/)).
- **Cancellation from the back office with the Close pending orders option**: one `updated_checkoutorder` per order **pending and being created**, broader than the automatic closing set on your shop.
- **Anti-churn postponement**: followed by **as many `created_shippingbox` as months postponed**.

> The most costly cascade in volume
>
> A change of address, carrier, variant, pickup point or customization triggers one `updated_shippingbox` per **shipment scheduled since the first day of the month before last (M-2, for example July 1st for a shipment in September)**, including those already shipped, plus one or two `updated_checkoutorder` per order being created. 12 recent shipments = **12 deliveries** for a single address change. Details on [Events: shipments](https://www.ciklik.academy/en/webhooks/evenements-expeditions/).

### Example

```json
{
    "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"
    }
}
```

## `deleted_subscription`

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

### When it is sent

- Deletion through the vendors API, `DELETE /subscriptions/{id}`, accepted only on an inactive (cancelled) subscription, 422 otherwise.
- Deletion from the back office (trash icon on the subscription record), only possible on an **inactive** subscription.

### When it is not sent

- **A cancellation**: produces an `updated_subscription`, never this webhook; these are two distinct actions.
- Restoring a deleted subscription: an `updated_subscription` (see above).

### What changed contains

Always `{"deleted": true}`.

### Cascading effects

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.

### Example

```json
{
    "changed": {
        "deleted": true
    }
}
```

## `updated_change_choices` on request

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](https://www.ciklik.academy/en/webhooks/configurer-les-webhooks-par-lapi/)), to be added in the **Webhooks** field of your site’s **Advanced** tab.

### When it is sent

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

### When it is not sent

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

### What changed contains

The same fields as the `updated_subscription` sent for the same action, always including `customization_products`: format trap, the value is **not** an object but a **string** containing encoded JSON, exactly as stored in the database.

### Cascading effects

`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).

### Example

```json
{
    "changed": {
        "customization_products": "[{\"id\":1,\"quantity\":2}]"
    }
}
```

## See also

[Understanding a webhook delivery](https://www.ciklik.academy/en/webhooks/comprendre-un-envoi-de-webhook/)

[Events: shipments](https://www.ciklik.academy/en/webhooks/evenements-expeditions/)

[Events: orders, transactions and invoices](https://www.ciklik.academy/en/webhooks/evenements-commandes-transactions-factures/)
