> This page is for API Reference.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.navipartner.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.navipartner.com/_mcp/server.

# Extend Membership

POST https://api.npretail.app/{tenant}/{environment}/{company}/membership/{membershipId}/extend
Content-Type: application/json

Use this endpoint to extend the duration of an active membership. The extension will **terminate the current period** and create a **new period starting from today**, based on the provided extension configuration. The **overall membership duration will be greater** than the original duration. You must provide the `itemNumber` from the `getExtendOptions` endpoint to apply the extension.

Reference: https://docs.navipartner.com/apis/api-reference/memberships/service-lifecycle/extend-membership

## Authentication

- `x-np-api-key` header (required) — API Key authentication via header

## Request

### Path parameters

- `tenant` (string, required) — Your Entra Tenant ID. [More details.](/paths#1-tenant)
- `environment` (string, required) — Your Business Central Environment. [More details.](/paths#2-environment)
- `company` (string, required) — Your Business Central Company. [More details.](/paths#3-company)
- `membershipId` (UUID, required) — Unique identifier for a membership.

### Body (application/json)

This endpoint expects an ExtendMembershipRequest.

- `optionId` (UUID, required) — Unique identifier for a membership alteration option.
- `documentNo` (string, optional) — External identifier for the sales document.
- `documentDate` (date, optional) — Specifies the date by which to base the extend calculation on. This is NOT the date by which the extend will actually take effect, and therefore you should not provide the `periodEnd` date from [Get Upgrade Options](/apis/api-reference/memberships/service-lifecycle/get-upgrade-options). If left empty, the system will assume today.

## Response

### 200

- `membership` (MembershipLifecycleEntriesDTO, required) — The MembershipLifecycleEntriesDTO is a composite type representing the timeline of a membership. It includes details when the membership was activated, renewed, upgraded, or extended.

## Types

### MembershipLifecycleEntriesDTO

The MembershipLifecycleEntriesDTO is a composite type representing the timeline of a membership. It includes details when the membership was activated, renewed, upgraded, or extended.

- `autoRenewalActivated` (boolean, required) — Indicates if the membership is set to auto-renew.
- `blocked` (boolean, required) — Indicates whether the entity is blocked.
- `communityCode` (string, required) — Code representing the community associated with the membership.
- `entries` (list of MembershipTimeEntryEntity, required)
- `issueDate` (date, required) — The date the membership was issued.
- `membershipCode` (string, required) — Code representing the type of membership.
- `membershipDescription` (string, required) — Description of the membership type.
- `membershipId` (UUID, required) — Unique identifier for a membership.
- `membershipNumber` (string, required) — Unique membership number.
- `attributes` (list of AttributeValueListResponse, optional)
- `blockedAt` (datetime, optional) — Date and time when the entity was blocked.
- `customerNumber` (string, optional) — Customer number associated with the membership.
- `documentId` (string, optional) — Unique identifier for the membership document.
- `validFromDate` (date, optional) — Start of the consecutive frame of the membership that is currently valid. `null` when the frame has no defined start — perpetual memberships, activate-on-first-use memberships that haven't been used yet, or memberships that aren't currently valid.
- `validUntilDate` (date, optional) — End of the consecutive frame of the membership that is currently valid. `9999-12-31` for perpetual memberships. `null` when the frame has no defined end — activate-on-first-use memberships that haven't been used yet, or memberships that aren't currently valid.

### MembershipTimeEntryEntity

The MembershipTimeEntryEntity describes the attributes of a time entry linked to a Membership. It is used within other composite DTOs to represent the validity associated with a membership.

- `entryId` (UUID, required) — Unique identifier for a time entry.
- `itemNumber` (string, required) — Unique identifier for an item.
- `lifecycleAction` (enum, required) — The lifecycle action for the membership.
  - Allowed values: `new`, `renew`, `upgrade`, `extend`, `cancel`, `autoRenew`, `regret`
- `blocked` (boolean, required) — Indicates whether the entity is blocked.
- `membershipCode` (string, required) — Code representing the type of membership.
- `description` (string, required) — Description of the entity.
- `createdAt` (datetime, required) — Date and time when the entity was created.
- `activateOnFirstUse` (boolean, required) — Specifies if the membership will activate upon first use.
- `documentNumber` (string, required) — External identifier for the sales document.
- `documentId` (string, required) — Unique identifier for the membership document.
- `unitPrice` (double, required) — The list price for the option.
- `amount` (double, required) — The amount associated with the membership.
- `amountInclVat` (double, required) — The amount including VAT associated with the membership.
- `originalLifecycleAction` (enum, optional) — The lifecycle action for the membership.
  - Allowed values: `new`, `renew`, `upgrade`, `extend`, `cancel`, `autoRenew`, `regret`
- `validFromDate` (date, optional) — Start of the consecutive frame of the membership that is currently valid. `null` when the frame has no defined start — perpetual memberships, activate-on-first-use memberships that haven't been used yet, or memberships that aren't currently valid.
- `validUntilDate` (date, optional) — End of the consecutive frame of the membership that is currently valid. `9999-12-31` for perpetual memberships. `null` when the frame has no defined end — activate-on-first-use memberships that haven't been used yet, or memberships that aren't currently valid.
- `linkedEntries` (list of MembershipTimeEntryLinkedEntries, optional)

### AttributeValueListResponse

This response contains a list of attribute values associated with a specific membership entity.

- `id` (UUID, required)
- `code` (string, required) — The key code for the attribute. This is a unique identifier for the attribute.
- `type` (enum, required) — The datatype of the attribute.
  - Allowed values: `text`, `code`, `date`, `datetime`, `decimal`, `integer`, `boolean`, `unknown`
- `caption` (string, required) — The caption of the attribute.
- `value` (string, required) — The value of the attribute. This is the actual data associated with the attribute.

### MembershipTimeEntryLinkedEntries

The linkedEntries describes the cancellation and regret entries linked to a Membership time entry.

- `entryId` (UUID, required)
- `entryNumber` (integer, required)
- `context` (string, required)
- `documentNumber` (string, required)
- `contextPeriodStartingDate` (date, required)
- `contextPeriodEndingDate` (date, required)
- `registrationDate` (datetime, required)

## Examples

**Request**

```json
{
  "optionId": "31111111-abcd-1234-5678-1234567890ac",
  "documentNo": "DOC654321"
}
```

**Response**

```json
{
  "membership": {
    "autoRenewalActivated": false,
    "blocked": false,
    "communityCode": "RIVERLAND",
    "entries": [
      {
        "entryId": "62349999-ffff-aaaa-bbbb-6234567890ff",
        "itemNumber": "M12345",
        "lifecycleAction": "new",
        "blocked": false,
        "membershipCode": "GOLD",
        "description": "A description of the time entry",
        "createdAt": "2024-09-17T00:00:00",
        "activateOnFirstUse": false,
        "documentNumber": "DOC123456",
        "documentId": "EA3AD944335C49DB962E4C854937990A",
        "unitPrice": 100,
        "amount": 80,
        "amountInclVat": 100,
        "validFromDate": "2024-09-17",
        "validUntilDate": "2024-10-07",
        "linkedEntries": [
          {
            "entryId": "596b6f52-e9fd-f011-a903-cb2b94ec3d40",
            "entryNumber": 18,
            "context": "cancel",
            "documentNumber": "DOC654321",
            "contextPeriodStartingDate": "2024-10-07",
            "contextPeriodEndingDate": "2025-09-16",
            "registrationDate": "2024-10-07T14:38:21.097Z"
          }
        ]
      },
      {
        "entryId": "52349999-eeee-ffff-aaaa-5234567890ef",
        "itemNumber": "EXTEND-12346",
        "lifecycleAction": "extend",
        "blocked": false,
        "membershipCode": "GOLD",
        "description": "A description of the time entry",
        "createdAt": "2024-09-17T00:00:00",
        "activateOnFirstUse": false,
        "documentNumber": "DOC654321",
        "documentId": "FFFFF944335C49DB962E4C854937990A",
        "unitPrice": 100,
        "amount": 80,
        "amountInclVat": 100,
        "validFromDate": "2024-10-08",
        "validUntilDate": "2025-10-07"
      }
    ],
    "issueDate": "2024-09-17",
    "membershipCode": "GOLD",
    "membershipDescription": "Gold Membership with premium benefits",
    "membershipId": "cdef7890-abcd-0123-1234-567890abcdef",
    "membershipNumber": "MS-DEMO-00152",
    "customerNumber": "D000188",
    "validFromDate": "2024-09-17",
    "validUntilDate": "2025-10-07"
  }
}
```

**SDK Code**

```python ExampleExtendMembership
import requests

url = "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend"

payload = {
    "optionId": "31111111-abcd-1234-5678-1234567890ac",
    "documentNo": "DOC654321"
}
headers = {
    "x-np-api-key": "<NaviPartner API Key>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript ExampleExtendMembership
const url = 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend';
const options = {
  method: 'POST',
  headers: {'x-np-api-key': '<NaviPartner API Key>', 'Content-Type': 'application/json'},
  body: '{"optionId":"31111111-abcd-1234-5678-1234567890ac","documentNo":"DOC654321"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go ExampleExtendMembership
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend"

	payload := strings.NewReader("{\n  \"optionId\": \"31111111-abcd-1234-5678-1234567890ac\",\n  \"documentNo\": \"DOC654321\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-np-api-key", "<NaviPartner API Key>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby ExampleExtendMembership
require 'uri'
require 'net/http'

url = URI("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-np-api-key"] = '<NaviPartner API Key>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"optionId\": \"31111111-abcd-1234-5678-1234567890ac\",\n  \"documentNo\": \"DOC654321\"\n}"

response = http.request(request)
puts response.read_body
```

```java ExampleExtendMembership
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend")
  .header("x-np-api-key", "<NaviPartner API Key>")
  .header("Content-Type", "application/json")
  .body("{\n  \"optionId\": \"31111111-abcd-1234-5678-1234567890ac\",\n  \"documentNo\": \"DOC654321\"\n}")
  .asString();
```

```php ExampleExtendMembership
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend', [
  'body' => '{
  "optionId": "31111111-abcd-1234-5678-1234567890ac",
  "documentNo": "DOC654321"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-np-api-key' => '<NaviPartner API Key>',
  ],
]);

echo $response->getBody();
```

```csharp ExampleExtendMembership
using RestSharp;

var client = new RestClient("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend");
var request = new RestRequest(Method.POST);
request.AddHeader("x-np-api-key", "<NaviPartner API Key>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"optionId\": \"31111111-abcd-1234-5678-1234567890ac\",\n  \"documentNo\": \"DOC654321\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift ExampleExtendMembership
import Foundation

let headers = [
  "x-np-api-key": "<NaviPartner API Key>",
  "Content-Type": "application/json"
]
let parameters = [
  "optionId": "31111111-abcd-1234-5678-1234567890ac",
  "documentNo": "DOC654321"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./membership/cdef7890-abcd-0123-1234-567890abcdef/extend")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```