> For the complete documentation index, see [llms.txt](https://docs.zotlo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zotlo.com/integrating-zotlo/webhooks/subscription-status-webhooks.md).

# Subscription Status Webhooks

Receive real-time updates about subscription lifecycle events

The **Subscription Status Webhook** notifies your server whenever a subscriber’s status changes, including new subscriptions, renewals, grace transitions, cancellations, reactivations, and quantity/package updates.

Use this webhook to keep your internal user access logic, CRM, analytics systems, and billing dashboards fully synchronized with Zotlo lifecycle events.

## **When This Is Triggered**

You will receive a callback when any of the following events occur:

| Event Type          | Description                                         |
| ------------------- | --------------------------------------------------- |
| **newSubscriber**   | A new subscription has been created (trial or paid) |
| **renewal**         | A subscription has successfully renewed             |
| **activeToGrace**   | Renewal failed → subscriber moved to grace period   |
| **graceToActive**   | A retry succeeded → subscriber returned to active   |
| **graceToPassive**  | All retries failed → subscription became passive    |
| **cancel**          | Subscription canceled by user, merchant, or system  |
| **reactivate**      | A canceled subscription was reactivated             |
| **package\_update** | The subscriber upgraded or downgraded their plan    |

## **Webhook Structure**

Every Subscription Status webhook contains two main sections:

* **queue** → event metadata
* **parameters** → full subscription profile and changes

## Example Payload

{% code overflow="wrap" %}

```json
{
  "queue": {
    "type": "SubscriberUpdate",
    "eventType": "newSubscriber",
    "requestID": "5a33b022-b877-4888-9eed-89a294640a3c",
    "createDate": {
      "date": "2024-05-13 08:18:22.978000",
      "timezone_type": 3,
      "timezone": "UTC"
    },
    "appId": 1651
  },
  "parameters": {
    "profile": {
      "status": "active",
      "realStatus": "active",
      "subscriberId": "testwebhook@mail.com",
      "subscriptionId": 10414,
      "subscriptionType": "trial",
      "startDate": "2024-05-13 08:18:22",
      "expireDate": "2024-05-16 08:18:22",
      "renewalDate": "2024-05-16 08:18:22",
      "package": "paypal_test",
      "country": "US",
      "phoneNumber": null,
      "language": "en",
      "originalTransactionId": "bfe87fcd-72f7-4902-88ba-b2695c829590",
      "lastTransactionId": "bfe87fcd-72f7-4902-88b2695c829590",
      "subscriptionPackageType": "single",
      "cancellation": null,
      "customParameters": {
        "clientUuid": "5adf7031-34f3-402b-88fc-2fe8cc87d0af"
      },
      "quantity": 1,
      "pendingQuantity": 0,
      "renewalFetchCount": 0
    },
    "package": {
      "packageId": "pro_test",
      "price": 1,
      "currency": "USD",
      "packageType": "subscription",
      "name": "pro_test",
      "subscriptionPackageType": "single",
      "bundlePackages": []
    },
    "newPackage": null,
    "card": {
      "cardNumber": "41111111****1111",
      "expireDate": "06/2024",
      "tokenId": 11082
    },
    "customer": null,
    "package_update": 0
  }
}
```

{% endcode %}

## **Field Reference**

#### **queue**

Metadata describing the event:

| Field                | Description                                                       |
| -------------------- | ----------------------------------------------------------------- |
| **queue.type**       | Always `SubscriberUpdate`                                         |
| **queue.eventType**  | Type of subscription event (renewal, cancel, newSubscriber, etc.) |
| **queue.requestID**  | Unique identifier for this webhook call                           |
| **queue.createDate** | Timestamp of the event                                            |
| **queue.appId**      | ID of the project where the transaction occurred                  |

#### **parameters.profile**

Current subscription profile and lifecycle state:

| Field                     | Description                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------ |
| **status**                | Current status → `active`, `grace`, or `passive`                                     |
| **realStatus**            | The true state (canceled users return `passive` immediately even if cycle not ended) |
| **subscriptionType**      | `trial` or `paid`                                                                    |
| **subscriberId**          | Unique identifier sent during purchase (email or phone)                              |
| **subscriptionId**        | Internal Zotlo subscription record ID                                                |
| **startDate**             | Subscription start date                                                              |
| **expireDate**            | Access expiration date                                                               |
| **renewalDate**           | Scheduled next billing attempt                                                       |
| **package**               | Current packageId                                                                    |
| **originalTransactionId** | First purchase transactionId                                                         |
| **lastTransactionId**     | Latest successful payment transactionId                                              |
| **country**               | Subscriber’s country                                                                 |
| **language**              | Subscriber’s preferred language                                                      |
| **cancellation**          | Cancellation details if subscription was canceled                                    |
| **quantity**              | Current billable quantity                                                            |
| **pendingQuantity**       | Quantity change that will apply on next renewal                                      |
| **customParameters**      | Custom metadata sent during purchase                                                 |

#### **parameters.package**

Information about the package currently active or last used.

| Field           | Description             |
| --------------- | ----------------------- |
| **packageId**   | ID of the package       |
| **price**       | Base price              |
| **currency**    | Currency                |
| **packageType** | subscription / one-time |
| **name**        | Display name            |

#### **parameters.newPackage**

Returned when a **downgrade** has occurred.\
`null` if no plan change happened.

#### **parameters.card**

Masked card details, if a card is used.

| Field          | Description       |
| -------------- | ----------------- |
| **cardNumber** | Masked card       |
| **expireDate** | Expiry date       |
| **tokenId**    | Tokenized card ID |

#### **parameters.customer**

Customer details (if applicable).\
May return `null`.

#### **parameters.package\_update**

Indicates whether this event was triggered after a plan change:

* `1` → package was updated
* `0` → no change

## **How to Use This Webhook**

Typical use cases:

* Update subscription status in your backend
* Grant or revoke access based on `status` or `realStatus`
* Trigger email notifications (trial ending, renewal success, cancellation)
* Update CRM / marketing automation
* Sync billing data to analytics systems
* Automate upgrade/downgrade flows

## **Logic for Access Control**

Use **realStatus** for determining true access logic when cancellations are involved:

* `status = active` but `realStatus = passive` → user canceled; access decision depends on your rules
* `status = grace` → payment failed; retry active; your app decides access
* `status = passive` → subscription ended


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zotlo.com/integrating-zotlo/webhooks/subscription-status-webhooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
