# Tenant provisioning change

A common problem with SaaS applications is that as they mature there is a disconnect between the features a customer has subscribed and paid for versus what they actually get.

It might be that they are paying for features that were never unlocked on their account. Which will result in less utility, a lower customer experience and possibly see the account churn.

Alternately they may have access to features they have not paid for due to an account manager enabling a feature on trial and then forgetting to actually charge them for it. In this case you will be unaware that there is an upsell opportunity available.

In either case, the upshot is that keeping your SaaS tenants in sync with subscriptions has a direct correlation with revenue. Bunny helps you keep in sync through a concept that we call tenant provisioning.

{% hint style="warning" %}
You can keep your tenants in sync by enabling a webhook from Bunny to notify you when subscriptions change or new features are added to a product.
{% endhint %}

### Prerequisites

To enable tenant provisioning you will need the following

* A **Platform** set up in Bunny with we [**webhook endpoint**](/developer/webhooks/webhooks.md) and **provisioning enabled**.
* A **Product** set up for the platform.
* A account with **subscription** to the product. If you have not created a subscription yet then you can do this via the UI or [by following this guide](/developer/bunny-sdk/create-a-subscription.md).

### Triggering the webhook

Bunny will send a webhook every time a change is made to a subscription. This includes the following:

* When **subscription state changes** from trial to active to canceled etc
* When **features** are added to a product that is included in the subscription
* When the quoted **quantities** for users etc are changed

{% hint style="warning" %}
You can debug webhooks and resend then using the Webhook log in your Bunny account. Find this under **Other > Webhook logs**.
{% endhint %}

The webhooks are sent using Bunny workflows which are enabled by default in every Bunny account.

If you want to customize the webhook payloads you can do that under the **Workflows > Tenant Provisioning** menu.

### The webhook payload

When a provisioning action is triggered the webhook will be sent as HTTP POST request to the url that you specified in the workflow recipe.

The webhook payload will be in the body of the request and contain information about the subscription state, account, product, features and the tenant in your SaaS application that requires an update.

We expect your webhook endpoint to return a HTTP 200 response.

```json
{
  "type": "TenantProvisioningChange",
  "payload": {
    "tenant": {
      "id": 23500,
      "code": "superdesk-1234",
      "name": "Superdesk Inc",
      "platform": {
        "id": 95,
        "code": "main",
        "name": "Main"
      },
      "account": {
        "id": 31455,
        "name": "Superdesk Inc",
        "billing_day": 16,
        "contacts": [
          {
            "id": 31059,
            "first_name": "Doug",
            "last_name": "Holes",
            "email": "doug@example.com"
          }
        ]
      }
    },
    "change": {
      "features": [
        {
          "code": "notes",
          "name": "Notes",
          "value": "",
          "quantity": 15
        }        
      ],
      "subscriptions": [
        {
          "id": 31782,
          "state": "active",
          "start_date": "2024-01-16",
          "end_date": "2024-02-15",
          "trial_start_date": "2024-01-02",
          "trial_end_date": "2024-01-15",
          "plan": {
            "code": "bronze",
            "name": "Bronze"
          },
          "price_list": {
            "code": "bronze_monthly",
            "name": "Monthly"
          },
          "features": [
            {
              "code": "notes",
              "name": "Notes",
              "value": "",
              "quantity": 15
            }
          ]
        }
      ]
    }
  }
}
```

### How to use the tenant provisioning change webhook?

#### Create or update a tenant in your SaaS application

In the webhook payload you will see a `tenant.code` attribute which should be used to find the tenant in your SaaS application to update.

Optionally, if the tenant doesnt exist in your platform then you could provision a new tenant.

{% hint style="warning" %}
The tenantCode is set when you [create a subscription](/developer/bunny-sdk/create-a-subscription.md) in Bunny.
{% endhint %}

*For example,* in this case we should look for a tenant in the SaaS application with an ID of `164`

```json
"tenant": {
  "code": "164",
  "platform": {
    "code": "main"
  }
},
```

If the tenant exists then the next step is to [update the features and usage limits](#update-features-and-set-limits) so that they are in sync with the subscription details.

#### Update features and set limits

The webhook payload contains a set of features and subscriptions that this particular tenant is subscribed to. In most cases you will only have a single subscription but Bunny is able to manage multiple subscriptions if you have several products available to the tenant.

The payload has a **features** attribute that tells you the features that should be enabled on the tenant as well as the limits that should be enforced.

*For example,* this subscription should be limited to **10 users** and have the **SSO** feature available.

```json
{
    "type": "TenantProvisioningChange",
    "payload": {
        "tenant": {
            "id": 311,
            "code": "superdesk-123456",
            "name": "Superdesk",
            "platform": {
                "id": 1,
                "code": "main",
                "name": "Main"
            },
            "account": {
                "id": 384,
                "name": "Superdesk",
                "billing_day": 14,
                "contacts": [
                    {
                        "id": 464,
                        "first_name": "Meg",
                        "last_name": "Ledon",
                        "email": "meg@example.com"
                    }
                ]
            }
        },
        "change": {
            "features": [
                {
                    "code": "sso",
                    "name": "SSO",
                    "quantity": null
                },
                {
                    "code": "users",
                    "name": "Users",
                    "quantity": 10
                }             
            ],
            "subscriptions": [
                {
                    "state": "active",
                    "start_date": "2022-12-13",
                    "end_date": "2023-12-12",
                    "trial_start_date": null,
                    "trial_end_date": null,
                    "product": {
                        "code": "business",
                        "name": "Business"
                    },
                    "plan": {
                        "code": null,
                        "name": "monthly"
                    },
                    "features": [
                        {
                            "code": "sso",
                            "name": "SSO",
                            "quantity": null
                        },
                        {
                            "code": "users",
                            "name": "Users",
                            "quantity": 10
                        }                        
                    ]
                }
            ]
        }
    }
}
```

{% hint style="warning" %}
To prevent headaches when you scale up you should only allow access to features if they are enabled on a subscription.

For example, if a tenant wanted to try a new feature, then you would first create it in Bunny and add it to their subscription. Then trigger the provisioning workflow to enable the feature on the tenant.
{% endhint %}


---

# Agent Instructions: 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.bunny.com/developer/webhooks/tenant-provisioning-change.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.
