> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bango.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Updating an entitlement

> Making sparse updates to an existing entitlement

In the Bango Platform, entitlements describe a user's ability to access a service provided by a merchant. To make changes to an existing entitlement, you send a `PATCH` request to the Bango Resale API.

You can't cancel, or revoke entitlements using `PATCH` requests: a `PATCH` **can't change the `status` property to `CANCELLED` or `REVOKED`**. Use the more specific [cancel](/legacy/resale/reseller/entitlements/cancel) or [revoke](/legacy/resale/reseller/entitlements/revoke) API requests instead.

As part of the API request, you supply:

* The entitlement ID.
* Other entitlement properties you want to change, such as `notificationUrl`, `dateExpiry`, or any custom `extensionData`. See [Bango Resale / For resellers / Reseller API reference / Reseller API reference overview](/legacy/resale/reseller/api-ref/index).

You can suspend, or resume entitlements using `PATCH` requests. For more information see [suspend](/legacy/resale/reseller/entitlements/suspend) or [resume](/legacy/resale/reseller/entitlements/resume).

You can reverse a cancellation before the `dateEnded` is reached using `PATCH` requests. For more information see [cancel](/legacy/resale/reseller/entitlements/cancel).

The API response is a structure that contains:

* A response code, indicating the result of the request. Use this code to determine what to do next.
* For HTTP 2xx responses, the entitlement record.

Depending on merchant requirements and potentially other factors, the response code might indicate that your code needs to take some action as a result of the update request. For example, the update might require the user to visit a web page to perform a process. In this case the entitlement record returned contains your requested updates but with status `PENDING`, and any later change to status `ACTIVE` is `POST`ed to the entitlement's `notificationUrl`, if specified.

### Sequence diagrams

<AccordionGroup>
  <Accordion title="Update with no further action required">
    The Bango Platform updates the entitlement and the user does not have to perform a process. The entitlement status does not change.

    <Frame>
      <img src="https://mintcdn.com/bango/XycmWBpGULTmv_up/images/image-35.png?fit=max&auto=format&n=XycmWBpGULTmv_up&q=85&s=26d16ad8152c1e1b6920bffa34efaa49" alt="Image" width="504" height="334" data-path="images/image-35.png" />
    </Frame>
  </Accordion>

  <Accordion title="Update with required user process">
    The merchant requires the user to perform a process. The Bango Platform returns an updated entitlement with status `PENDING`, with the response code `CLIENT_ACTION_REQUIRED` and action `NAVIGATE_TO_URL`, together with the target URL. You send the user to the URL, and when the user completes the process the Bango Platform notifies you by direct server-to-server communication.

    <Frame>
      <img src="https://mintcdn.com/bango/XycmWBpGULTmv_up/images/image-35.png?fit=max&auto=format&n=XycmWBpGULTmv_up&q=85&s=26d16ad8152c1e1b6920bffa34efaa49" alt="Image" width="504" height="334" data-path="images/image-35.png" />
    </Frame>
  </Accordion>

  <Accordion title="Failed request to update entitlement">
    The Bango Platform can't update the entitlement, and returns the reason in the response to the API request.

    <Frame>
      <img src="https://mintcdn.com/bango/XycmWBpGULTmv_up/images/image-35.png?fit=max&auto=format&n=XycmWBpGULTmv_up&q=85&s=26d16ad8152c1e1b6920bffa34efaa49" alt="Image" width="504" height="334" data-path="images/image-35.png" />
    </Frame>
  </Accordion>
</AccordionGroup>

### Skeleton code

Here's some sample code in a C/Java-like language: adapt this code to your needs. Use the same API endpoint prefix with test credentials and with production credentials.

Some functions referenced in the skeleton code, such as `redirect_device_to`, are not defined. You need to implement these where possible.

```text theme={null}
function update_entitlement (entitlement_id, properties_to_update = {}) {
    // *Always* use this endpoint prefix for the Bango Resale API.
    const base_url = "https://resale.api.bango.net";

    // This is what's returned with HTTP 2xx.
    let entitlement = null;

    // The entitlement ID is passed in the body not the path.
    // Here, assume properties_to_update is a map of entitlement
    // property names to values.
    // See API ref for details of which properties you can update.
    const request_body_params = properties_to_update
        .copy()
        .set('entitlementId', entitlement_id);

    try {
        // PATCH UTF-8 JSON to the Bango Resale API and parse the JSON response
        let response = rest_client_call({
            method: "PATCH",
            url: base_url + "entitlement",
            headers: {
                "Authorization": get_authorization_header(),
                "Content-Type": "application/json",
            },
            body: make_json_string(request_body_params),
        }).from_json();

        // The responseCode tells us the result.
        switch (response.responseCode) {
            // Success: no action required
            case "OK":
                entitlement = response;
                break;

            // More to do: The reseller must take action
            case "CLIENT_ACTION_REQUIRED":
                // This response parameter tells us what we need to do.
                switch (response.parameters.action) {
                    case "NAVIGATE_TO_URL":
                        // Send the user to a particular web page
                        // to complete a merchant-defined process.
                        // Set entitlement's notificationUrl to
                        // receive notification of entitlement
                        // changes asynchronously.
                        redirect_device_to({
                            url: response.parameters.url,
                        });
                        // Updated entitlement is returned in this case
                        // but with status PENDING.
                        entitlement = response;
                        break;

                    default:
                        // Unrecognized action.
                        // Check the documentation again.
                        throw "Unrecognized client action";
                }

                break;

            // Failures
            // These may indicate issues in your code, not the Bango Platform.
            case "BAD_REQUEST": // Invalid request
            case "UNAUTHORIZED": // Check your credentials
            case "NOT_AVAILABLE": // Unable to update this entitlement
            case "NOT_FOUND": // Invalid entitlement ID
            case "TOO_MANY_REQUESTS": // Request limit reached: try again later
                throw "Unable to update entitlement";

            // Bango Platform issues
            // These likely indicate transient problems.
            // In production code, you might want to try the request again
            // after a delay, ultimately falling back to an error state.
            case "INTERNAL_ERROR":
            case "SERVICE_UNAVAILABLE":
                throw "Bango Platform unavailable";

            // This might indicate Bango has added a new response code.
            // Check the documentation again.
            default:
                throw "Unrecognized response code";
        }

    } catch (exception) {
        // Production code might want to notify the reseller in some way,
        // and/or log full details of the exception for later analysis,
        // and degrade gracefully for the user.
        output("An error occurred!");
        output(exception);
    }

    // null if entitlement not updated.
    // if updated, will have an entitlementId, status, and other properties:
    // see API reference.
    return entitlement;
}
```

### FAQ

<AccordionGroup>
  <Accordion title="Which request parameters should I set?">
    You must set the `entitlementId`. Include any other parameters you want to update: any parameter not included in the request is not changed.

    See [Bango Resale / For resellers / Reseller API reference / Reseller API reference overview](/legacy/resale/reseller/api-ref/index) for detailed information on all request parameters.
  </Accordion>

  <Accordion title="Why might I have to send the user to a web page?">
    It depends on the merchant, the user, the service, and possibly other factors. In most cases you won't have to do anything: the update request will return the response code `OK`.

    One likely reason for the response code `CLIENT_ACTION_REQUIRED` may be a change in `productKey`: perhaps you're upgrading the user to a new service tier, and the merchant requires an additional setup process.
  </Accordion>

  <Accordion title="What are all the possible API response structures?">
    All responses contain a `responseCode` string that indicates the result of the request. Use this code to determine how to react. For each distinct `responseCode`, the response might include other useful values.

    See [Bango Resale / For resellers / Reseller API reference / Reseller API reference overview](/legacy/resale/reseller/api-ref/index) for detailed information on all responses.
  </Accordion>
</AccordionGroup>
