# Product Package

**Summary:** Endpoints for Product Package

- Role: [Developers](https://www.subrite.no/developers)
- Source: https://www.subrite.no/developers/product-package
- Updated: 2026-10-13
- Markdown index: https://www.subrite.no/developers/llms.txt

<a id="get-api-v1-product-packages"></a>
## Get all packages of the tenant

`GET /api/v1/product-packages`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `page` | query | `number` | Default: `1` · `minimum`: `1` |
| `take` | query | `number` | Default: `10` · `minimum`: `1`, `maximum`: `50` |
| `orderDirection` | query | `string` | Allowed values: `"asc"`, `"desc"` · Default: `"desc"` |
| `orderBy` | query | `string` | Allowed values: `"createdAt"`, `"id"`, `"updatedAt"`, `"name"`, `"status"`, `"recurringPrice"`, `"price"` · Default: `"createdAt"` |
| `status` | query | `array of string` | Filter by one or more statuses · Allowed values: `"draft"`, `"published"`, `"archived"` |
| `billingPeriod` | query | `array of string` | Filter by one or more billing periods (subscription duration filter) · Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `recurringPriceMin` | query | `number` | Minimum recurring price (inclusive). Derived from package subscription products. · `minimum`: `0` |
| `recurringPriceMax` | query | `number` | Maximum recurring price (inclusive). Derived from package subscription products. · `minimum`: `0` |
| `priceMin` | query | `number` | Minimum intro price (inclusive). Derived from package products. · `minimum`: `0` |
| `priceMax` | query | `number` | Maximum intro price (inclusive). Derived from package products. · `minimum`: `0` |
| `createdAtFrom` | query | `string` | Created at from date (inclusive, ISO date). Filters package.createdAt. |
| `createdAtTo` | query | `string` | Created at to date (inclusive, ISO date). Filters package.createdAt. |
| `updatedAtFrom` | query | `string` | Updated at from date (inclusive, ISO date). Filters package.updatedAt. |
| `updatedAtTo` | query | `string` | Updated at to date (inclusive, ISO date). Filters package.updatedAt. |
| `isAvailableViaSlug` | query | `boolean` |   |
| `isAvailableOnMyPage` | query | `boolean` |   |
| `isAvailableForManualOrderViaAdmin` | query | `boolean` |   |
| `enableGiftSubscription` | query | `boolean` |   |
| `name` | query | `string` |   |

### Responses

#### 200

Content type: `application/json` · `PackageResponsePaginated`

| Name | Type | Description |
| --- | --- | --- |
| `items` (Required) | `array of PackageResponse` |   |
| `items[].paymentProviders` (Required when parent is present) | `array of PAYMENT_PROVIDER` | Allowed values: `"stripe"`, `"vipps"`, `"external"`, `"nets"`, `"efaktura-avtalegiro-ehf"`, `"swedbankpay"` |
| `items[].repeatPurchaseControl` (Required when parent is present) | `RepeatPurchaseControl` | Allowed values: `"allow"`, `"warning"`, `"block_active"`, `"block_forever"`, `"cooldown"` |
| `items[].repeatPurchaseCooldownDays` | `number` | Can be null |
| `items[].displayOrder` | `number` | Can be null |
| `items[].seo` (Required when parent is present) | `Seo` |   |
| `items[].seo.noIndex` (Required when parent is present) | `boolean` | Ask search engines not to index the resource's own page — for a package, its checkout page (robots "noindex"). The page stays reachable by direct link. |
| `items[].seo.noFollow` (Required when parent is present) | `boolean` | Ask search engines not to follow links on the resource's own page — for a package, its checkout page (robots "nofollow"). |
| `items[].onboardingWelcomeRedirectCTAText` (Required when parent is present) | `Translation` | Can be null |
| `items[].onboardingWelcomeRedirectCTAText.en` (Required when parent is present) | `string` |   |
| `items[].onboardingWelcomeRedirectCTAText.no` (Required when parent is present) | `string` |   |
| `items[].onboardingWelcomeRedirectCTAText.sv` | `string` |   |
| `items[].onboardingWelcomeRedirectCTAText.da` | `string` |   |
| `items[].onboardingWelcomeRedirectCTAText.key` | `string` |   |
| `items[].customPeriodText` (Required when parent is present) | `Translation` | Can be null |
| `items[].customPeriodText.en` (Required when parent is present) | `string` |   |
| `items[].customPeriodText.no` (Required when parent is present) | `string` |   |
| `items[].customPeriodText.sv` | `string` |   |
| `items[].customPeriodText.da` | `string` |   |
| `items[].customPeriodText.key` | `string` |   |
| `items[].subscriptionCount` (Required when parent is present) | `number` |   |
| `items[].products` (Required when parent is present) | `array of PackProduct` | Can be null |
| `items[].products[].productId` (Required when parent is present) | `number` |   |
| `items[].products[].name` (Required when parent is present) | `string` |   |
| `items[].products[].price` (Required when parent is present) | `number` |   |
| `items[].products[].currency` (Required when parent is present) | `string` |   |
| `items[].products[].tax` (Required when parent is present) | `number` |   |
| `items[].products[].basePrice` (Required when parent is present) | `number` |   |
| `items[].products[].recurringPrice` (Required when parent is present) | `number` |   |
| `items[].products[].isOptional` (Required when parent is present) | `boolean` |   |
| `items[].products[].productCategory` (Required when parent is present) | `string` | Allowed values: `"digital_subscription"`, `"physical_subscription"`, `"physical"`, `"event_ticket"`, `"PHYSICAL_PRODUCT"` |
| `items[].products[].circulationType` | `CIRCULATION_TYPE` | Allowed values: `"subscription"`, `"single_copy"` · Can be null |
| `items[].products[].properties` (Required when parent is present) | `OptionalProductProperties` | Can be null · Nested fields omitted: depth limit. |
| `items[].products[].recurringProperties` (Required when parent is present) | `OptionalProductProperties` | Can be null · Nested fields omitted: depth limit. |
| `items[].products[].shippingCharges` (Required when parent is present) | `array of ShippingCharge` | Nested fields omitted: depth limit. |
| `items[].products[].description` (Required when parent is present) | `string` |   |
| `items[].price` (Required when parent is present) | `number` | Default: `0` |
| `items[].recurringPrice` (Required when parent is present) | `number` |   |
| `items[].isAvailableOnMyPage` (Required when parent is present) | `boolean` |   |
| `items[].isAvailableForManualOrderViaAdmin` (Required when parent is present) | `boolean` |   |
| `items[].customInputFields` (Required when parent is present) | `CustomInputFields` |   |
| `items[].customInputFields.memberType` (Required when parent is present) | `boolean` |   |
| `items[].customInputFields.invoiceAddress` (Required when parent is present) | `boolean` |   |
| `items[].customInputFields.city` (Required when parent is present) | `boolean` |   |
| `items[].salesTitle` (Required when parent is present) | `string` |   |
| `items[].uuid` (Required when parent is present) | `string` |   |
| `items[].subscriptionPlanId` (Required when parent is present) | `number` |   |
| `items[].slug` (Required when parent is present) | `string` |   |
| `items[].image` (Required when parent is present) | `string` |   |
| `items[].name` (Required when parent is present) | `string` |   |
| `items[].description` (Required when parent is present) | `object` |   |
| `items[].billingPeriod` (Required when parent is present) | `string` | Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `items[].billingPeriodUnit` (Required when parent is present) | `string` | Allowed values: `"day"`, `"week"`, `"month"`, `"year"` |
| `items[].billingPeriodFrequency` (Required when parent is present) | `number` |   |
| `items[].status` (Required when parent is present) | `string` | Allowed values: `"draft"`, `"published"`, `"archived"` |
| `items[].isAvailableViaSlug` (Required when parent is present) | `boolean` |   |
| `items[].allowSameSubscriptionChange` (Required when parent is present) | `boolean` |   |
| `items[].allowDifferentSubscriptionSwitch` (Required when parent is present) | `boolean` |   |
| `items[].tenantId` (Required when parent is present) | `number` |   |
| `items[].orderCtaLabel` (Required when parent is present) | `Translation` | Nested fields omitted: field limit. |
| `items[].introPeriodFixedEndDate` (Required when parent is present) | `string (date-time)` |   |
| `items[].packageProducts` (Required when parent is present) | `array of PackageProduct` | Nested fields omitted: field limit. |
| `items[].subscriptionPlan` (Required when parent is present) | `SubscriptionPlan` | Nested fields omitted: field limit. |
| `items[].payments` (Required when parent is present) | `array of Payment` | Nested fields omitted: field limit. |
| `items[].memberPackages` (Required when parent is present) | `array of MemberPackage` | Nested fields omitted: field limit. |
| `items[].id` (Required when parent is present) | `number` |   |
| `items[].createdAt` (Required when parent is present) | `string (date-time)` |   |
| `items[].updatedAt` (Required when parent is present) | `string (date-time)` |   |
| `items[].deletedAt` (Required when parent is present) | `string (date-time)` |   |
| `items[].metaData` (Required when parent is present) | `object` |   |
| `meta` (Required) | `PageMeta` |   |
| `meta.page` (Required) | `number` |   |
| `meta.take` (Required) | `number` |   |
| `meta.count` (Required) | `number` |   |
| `meta.pageCount` (Required) | `number` |   |
| `meta.hasPreviousPage` (Required) | `boolean` |   |
| `meta.hasNextPage` (Required) | `boolean` |   |

#### 400

Content type: `application/json` · `ErrorResponse`

Query validation failed; field codes in errors\[\]

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"`, `"internalServerError"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` |   |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
{
  "items": [
    {
      "paymentProviders": [],
      "products": [],
      "description": {},
      "packageProducts": [],
      "payments": [],
      "memberPackages": [],
      "metaData": {}
    }
  ],
  "meta": {
    "page": 0,
    "take": 0,
    "count": 0,
    "pageCount": 0,
    "hasPreviousPage": true,
    "hasNextPage": true
  }
}
```

<a id="post-api-v1-product-packages"></a>
## Create a new package

`POST /api/v1/product-packages`

**Authentication:** Bearer token (JWT)

### Request body

Content type: `multipart/form-data` · Required · `CreatePackageDto`

| Name | Type | Description |
| --- | --- | --- |
| `salesTitle` (Required) | `string` |   |
| `slug` | `string` |   |
| `subscriptionPlanId` | `number` | `minimum`: `1` |
| `name` (Required) | `string` |   |
| `paymentProviders` (Required) | `array of PAYMENT_PROVIDER` | Allowed values: `"stripe"`, `"vipps"`, `"external"`, `"nets"`, `"efaktura-avtalegiro-ehf"`, `"swedbankpay"` · `minItems`: `1` |
| `description` | `string` |   |
| `image` | `file` |   |
| `imageUrl` | `string (uri)` | Public URL of a file in the Assets library to use as the package image, instead of uploading bytes. The file is referenced rather than copied. |
| `billingPeriod` | `string` | Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `billingPeriodUnit` | `string` | Allowed values: `"day"`, `"week"`, `"month"`, `"year"` |
| `billingPeriodFrequency` | `number` | `minimum`: `1` |
| `status` (Required) | `string` | Allowed values: `"draft"`, `"published"`, `"archived"` |
| `isAvailableOnMyPage` | `boolean` |   |
| `isAvailableViaSlug` | `boolean` |   |
| `isAvailableForManualOrderViaAdmin` | `boolean` |   |
| `onboardingWelcomeRedirectCTAText` (Required) | `Translation` |   |
| `onboardingWelcomeRedirectCTAText.en` (Required) | `string` |   |
| `onboardingWelcomeRedirectCTAText.no` (Required) | `string` |   |
| `onboardingWelcomeRedirectCTAText.sv` | `string` |   |
| `onboardingWelcomeRedirectCTAText.da` | `string` |   |
| `onboardingWelcomeRedirectCTAText.key` | `string` |   |
| `customPeriodText` | `Translation` |   |
| `customPeriodText.en` (Required when parent is present) | `string` |   |
| `customPeriodText.no` (Required when parent is present) | `string` |   |
| `customPeriodText.sv` | `string` |   |
| `customPeriodText.da` | `string` |   |
| `customPeriodText.key` | `string` |   |
| `orderCtaLabel` | `Translation` |   |
| `orderCtaLabel.en` (Required when parent is present) | `string` |   |
| `orderCtaLabel.no` (Required when parent is present) | `string` |   |
| `orderCtaLabel.sv` | `string` |   |
| `orderCtaLabel.da` | `string` |   |
| `orderCtaLabel.key` | `string` |   |
| `seo` | `Seo` |   |
| `seo.noIndex` (Required when parent is present) | `boolean` | Ask search engines not to index the resource's own page — for a package, its checkout page (robots "noindex"). The page stays reachable by direct link. |
| `seo.noFollow` (Required when parent is present) | `boolean` | Ask search engines not to follow links on the resource's own page — for a package, its checkout page (robots "nofollow"). |
| `products` | `array of PackageProductDto` | `minItems`: `1` |
| `products[].productId` (Required when parent is present) | `number` | `minimum`: `1` |
| `products[].price` (Required when parent is present) | `number` | `minimum`: `0` |
| `products[].properties` | `OptionalProductProperties` |   |
| `products[].properties.isRequired` (Required when parent is present) | `boolean` |   |
| `products[].properties.quantityRange` (Required when parent is present) | `number` |   |
| `introPeriodFixedEndDate` | `string (date-time)` |   |
| `repeatPurchaseControl` | `RepeatPurchaseControl` | Allowed values: `"allow"`, `"warning"`, `"block_active"`, `"block_forever"`, `"cooldown"` |
| `repeatPurchaseCooldownDays` | `number` | `minimum`: `1` |

### Responses

#### 201

Content type: `application/json` · `PackageResponse`

| Name | Type | Description |
| --- | --- | --- |
| `paymentProviders` (Required) | `array of PAYMENT_PROVIDER` | Allowed values: `"stripe"`, `"vipps"`, `"external"`, `"nets"`, `"efaktura-avtalegiro-ehf"`, `"swedbankpay"` |
| `repeatPurchaseControl` (Required) | `RepeatPurchaseControl` | Allowed values: `"allow"`, `"warning"`, `"block_active"`, `"block_forever"`, `"cooldown"` |
| `repeatPurchaseCooldownDays` | `number` | Can be null |
| `displayOrder` | `number` | Can be null |
| `seo` (Required) | `Seo` |   |
| `seo.noIndex` (Required) | `boolean` | Ask search engines not to index the resource's own page — for a package, its checkout page (robots "noindex"). The page stays reachable by direct link. |
| `seo.noFollow` (Required) | `boolean` | Ask search engines not to follow links on the resource's own page — for a package, its checkout page (robots "nofollow"). |
| `onboardingWelcomeRedirectCTAText` (Required) | `Translation` | Can be null |
| `onboardingWelcomeRedirectCTAText.en` (Required when parent is present) | `string` |   |
| `onboardingWelcomeRedirectCTAText.no` (Required when parent is present) | `string` |   |
| `onboardingWelcomeRedirectCTAText.sv` | `string` |   |
| `onboardingWelcomeRedirectCTAText.da` | `string` |   |
| `onboardingWelcomeRedirectCTAText.key` | `string` |   |
| `customPeriodText` (Required) | `Translation` | Can be null |
| `customPeriodText.en` (Required when parent is present) | `string` |   |
| `customPeriodText.no` (Required when parent is present) | `string` |   |
| `customPeriodText.sv` | `string` |   |
| `customPeriodText.da` | `string` |   |
| `customPeriodText.key` | `string` |   |
| `subscriptionCount` (Required) | `number` |   |
| `products` (Required) | `array of PackProduct` | Can be null |
| `products[].productId` (Required when parent is present) | `number` |   |
| `products[].name` (Required when parent is present) | `string` |   |
| `products[].price` (Required when parent is present) | `number` |   |
| `products[].currency` (Required when parent is present) | `string` |   |
| `products[].tax` (Required when parent is present) | `number` |   |
| `products[].basePrice` (Required when parent is present) | `number` |   |
| `products[].recurringPrice` (Required when parent is present) | `number` |   |
| `products[].isOptional` (Required when parent is present) | `boolean` |   |
| `products[].productCategory` (Required when parent is present) | `string` | Allowed values: `"digital_subscription"`, `"physical_subscription"`, `"physical"`, `"event_ticket"`, `"PHYSICAL_PRODUCT"` |
| `products[].circulationType` | `CIRCULATION_TYPE` | Allowed values: `"subscription"`, `"single_copy"` · Can be null |
| `products[].properties` (Required when parent is present) | `OptionalProductProperties` | Can be null |
| `products[].properties.isRequired` (Required when parent is present) | `boolean` |   |
| `products[].properties.quantityRange` (Required when parent is present) | `number` |   |
| `products[].recurringProperties` (Required when parent is present) | `OptionalProductProperties` | Can be null |
| `products[].recurringProperties.isRequired` (Required when parent is present) | `boolean` |   |
| `products[].recurringProperties.quantityRange` (Required when parent is present) | `number` |   |
| `products[].shippingCharges` (Required when parent is present) | `array of ShippingCharge` |   |
| `products[].shippingCharges[].country` (Required when parent is present) | `string` |   |
| `products[].shippingCharges[].charge` (Required when parent is present) | `number` |   |
| `products[].description` (Required when parent is present) | `string` |   |
| `price` (Required) | `number` | Default: `0` |
| `recurringPrice` (Required) | `number` |   |
| `isAvailableOnMyPage` (Required) | `boolean` |   |
| `isAvailableForManualOrderViaAdmin` (Required) | `boolean` |   |
| `customInputFields` (Required) | `CustomInputFields` |   |
| `customInputFields.memberType` (Required) | `boolean` |   |
| `customInputFields.invoiceAddress` (Required) | `boolean` |   |
| `customInputFields.city` (Required) | `boolean` |   |
| `salesTitle` (Required) | `string` |   |
| `uuid` (Required) | `string` |   |
| `subscriptionPlanId` (Required) | `number` |   |
| `slug` (Required) | `string` |   |
| `image` (Required) | `string` |   |
| `name` (Required) | `string` |   |
| `description` (Required) | `object` |   |
| `billingPeriod` (Required) | `string` | Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `billingPeriodUnit` (Required) | `string` | Allowed values: `"day"`, `"week"`, `"month"`, `"year"` |
| `billingPeriodFrequency` (Required) | `number` |   |
| `status` (Required) | `string` | Allowed values: `"draft"`, `"published"`, `"archived"` |
| `isAvailableViaSlug` (Required) | `boolean` |   |
| `allowSameSubscriptionChange` (Required) | `boolean` |   |
| `allowDifferentSubscriptionSwitch` (Required) | `boolean` |   |
| `tenantId` (Required) | `number` |   |
| `orderCtaLabel` (Required) | `Translation` |   |
| `orderCtaLabel.en` (Required) | `string` |   |
| `orderCtaLabel.no` (Required) | `string` |   |
| `orderCtaLabel.sv` | `string` |   |
| `orderCtaLabel.da` | `string` |   |
| `orderCtaLabel.key` | `string` |   |
| `introPeriodFixedEndDate` (Required) | `string (date-time)` |   |
| `packageProducts` (Required) | `array of PackageProduct` | Nested fields omitted: field limit. |
| `subscriptionPlan` (Required) | `SubscriptionPlan` | Nested fields omitted: field limit. |
| `payments` (Required) | `array of Payment` | Nested fields omitted: field limit. |
| `memberPackages` (Required) | `array of MemberPackage` | Nested fields omitted: field limit. |
| `id` (Required) | `number` |   |
| `createdAt` (Required) | `string (date-time)` |   |
| `updatedAt` (Required) | `string (date-time)` |   |
| `deletedAt` (Required) | `string (date-time)` |   |
| `metaData` (Required) | `object` |   |

#### 400

Content type: `application/json` · `ErrorResponse`

Body validation failed, a product id is unknown, the plan products are not all included, or the intro-period/billing-period combination is invalid; field codes in errors\[\]

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"`, `"internalServerError"`, `"invalidProducts"`, `"missingProducts"`, `"setEitherIntroPeriodFixedEndDateOrBillingPeriod"`, `"introPeriodFixedEndDateAndBillingPeriodCannotCoexist"`, `"missingUnitOrFrequencyForCustomBillingPeriod"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 404

Content type: `application/json` · `ErrorResponse`

subscriptionPlanNotFound

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"subscriptionPlanNotFound"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "subscriptionPlanNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 413

fileSizeExceeded

#### 415

invalidFileType

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 502

Content type: `application/json` · `ErrorResponse`

The image could not be stored; the package was not created

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"packageImageUploadFailed"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "packageImageUploadFailed",
  "message": "string",
  "errors": [
    {}
  ]
}
```

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages \
  --request POST \
  --header 'Authorization: Bearer <token>' \
  --form 'salesTitle=string' \
  --form 'name=string' \
  --form 'image=@<file>' \
  --form 'status=draft'
```

### Example response

201 · `application/json`

```json
{
  "paymentProviders": [
    "stripe"
  ],
  "repeatPurchaseControl": "allow",
  "repeatPurchaseCooldownDays": 0,
  "displayOrder": 0,
  "seo": {
    "noIndex": true,
    "noFollow": true
  },
  "onboardingWelcomeRedirectCTAText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "customPeriodText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "subscriptionCount": 0,
  "products": [
    {
      "shippingCharges": []
    }
  ],
  "price": 0,
  "recurringPrice": 0,
  "isAvailableOnMyPage": true,
  "isAvailableForManualOrderViaAdmin": true,
  "customInputFields": {
    "memberType": true,
    "invoiceAddress": true,
    "city": true
  },
  "salesTitle": "string",
  "uuid": "string",
  "subscriptionPlanId": 0,
  "slug": "string",
  "image": "string",
  "name": "string",
  "description": {},
  "billingPeriod": "monthly",
  "billingPeriodUnit": "day",
  "billingPeriodFrequency": 0,
  "status": "draft",
  "isAvailableViaSlug": true,
  "allowSameSubscriptionChange": true,
  "allowDifferentSubscriptionSwitch": true,
  "tenantId": 0,
  "orderCtaLabel": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "introPeriodFixedEndDate": "2019-08-24T14:15:22Z",
  "packageProducts": [
    {
      "metaData": {}
    }
  ],
  "subscriptionPlan": {
    "paymentProviders": [],
    "name": "string",
    "uuid": "string",
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "autoRenew": true,
    "status": "draft",
    "tenantId": 0,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "allowAdminSameSubscriptionChange": true,
    "allowAdminDifferentSubscriptionSwitch": true,
    "enableGiftSubscription": true,
    "allowFutureStartDate": true,
    "showAsOptionOnSubscriptionSwitch": true,
    "showAsOptionOnAdminSubscriptionSwitch": true,
    "offerSwitchOnCheckout": true,
    "tenant": {
      "additionalFeatures": [],
      "disabledFeatures": [],
      "taxRates": [],
      "products": [],
      "users": [],
      "members": [],
      "roles": [],
      "subscriptionPlans": [],
      "packages": [],
      "invoices": [],
      "orders": [],
      "paymentProviders": [],
      "newslettersProviderConfig": [],
      "paymentProviderConfigs": [],
      "oidcClients": [],
      "oauthProviders": [],
      "activityLogs": [],
      "m2m_api_clients": [],
      "customProperties": [],
      "consents": [],
      "communicationTemplates": [],
      "additionalHostnames": [],
      "exportHistory": [],
      "arReportHistory": [],
      "mypageCardsSettings": [],
      "webhooks": [],
      "customOrders": [],
      "customOrderSources": [],
      "brandKits": [],
      "communicationReceivers": [],
      "metaData": {}
    },
    "entityTags": [],
    "subscriptionPlanProducts": [],
    "packages": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "payments": [
    {
      "metaData": {}
    }
  ],
  "memberPackages": [
    {
      "memberPackageProducts": [],
      "orders": [],
      "changes": [],
      "histories": [],
      "metaData": {}
    }
  ],
  "id": 0,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "deletedAt": "2019-08-24T14:15:22Z",
  "metaData": {}
}
```

<a id="get-api-v1-product-packages-free"></a>
## Get free packages

`GET /api/v1/product-packages/free`

**Authentication:** Bearer token (JWT)

### Responses

#### 200

Content type: `application/json` · `array of MinimalPackageResponse`

| Name | Type | Description |
| --- | --- | --- |
| `[].packName` (Required when parent is present) | `string` |   |
| `[].name` (Required when parent is present) | `string` |   |
| `[].id` (Required when parent is present) | `number` |   |
| `[].slug` (Required when parent is present) | `string` |   |

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages/free \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
[
  {
    "packName": "string",
    "name": "string",
    "id": 0,
    "slug": "string"
  }
]
```

<a id="get-api-v1-product-packages-manual-order"></a>
## Get packages available for manual order by admin

`GET /api/v1/product-packages/manual-order`

**Authentication:** Bearer token (JWT)

### Responses

#### 200

Content type: `application/json` · `array of MinimalPackageResponse`

| Name | Type | Description |
| --- | --- | --- |
| `[].packName` (Required when parent is present) | `string` |   |
| `[].name` (Required when parent is present) | `string` |   |
| `[].id` (Required when parent is present) | `number` |   |
| `[].slug` (Required when parent is present) | `string` |   |

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages/manual-order \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
[
  {
    "packName": "string",
    "name": "string",
    "id": 0,
    "slug": "string"
  }
]
```

<a id="get-api-v1-product-packages-all"></a>
## Get packages by filters

`GET /api/v1/product-packages/all`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `status` | query | `array of string` | Filter by one or more statuses · Allowed values: `"draft"`, `"published"`, `"archived"` |
| `billingPeriod` | query | `array of string` | Filter by one or more billing periods (subscription duration filter) · Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `recurringPriceMin` | query | `number` | Minimum recurring price (inclusive). Derived from package subscription products. · `minimum`: `0` |
| `recurringPriceMax` | query | `number` | Maximum recurring price (inclusive). Derived from package subscription products. · `minimum`: `0` |
| `priceMin` | query | `number` | Minimum intro price (inclusive). Derived from package products. · `minimum`: `0` |
| `priceMax` | query | `number` | Maximum intro price (inclusive). Derived from package products. · `minimum`: `0` |
| `createdAtFrom` | query | `string` | Created at from date (inclusive, ISO date). Filters package.createdAt. |
| `createdAtTo` | query | `string` | Created at to date (inclusive, ISO date). Filters package.createdAt. |
| `updatedAtFrom` | query | `string` | Updated at from date (inclusive, ISO date). Filters package.updatedAt. |
| `updatedAtTo` | query | `string` | Updated at to date (inclusive, ISO date). Filters package.updatedAt. |
| `isAvailableViaSlug` | query | `boolean` |   |
| `isAvailableOnMyPage` | query | `boolean` |   |
| `isAvailableForManualOrderViaAdmin` | query | `boolean` |   |
| `enableGiftSubscription` | query | `boolean` |   |
| `name` | query | `string` |   |

### Responses

#### 200

Content type: `application/json` · `array of PackageResponse`

| Name | Type | Description |
| --- | --- | --- |
| `[].paymentProviders` (Required when parent is present) | `array of PAYMENT_PROVIDER` | Allowed values: `"stripe"`, `"vipps"`, `"external"`, `"nets"`, `"efaktura-avtalegiro-ehf"`, `"swedbankpay"` |
| `[].repeatPurchaseControl` (Required when parent is present) | `RepeatPurchaseControl` | Allowed values: `"allow"`, `"warning"`, `"block_active"`, `"block_forever"`, `"cooldown"` |
| `[].repeatPurchaseCooldownDays` | `number` | Can be null |
| `[].displayOrder` | `number` | Can be null |
| `[].seo` (Required when parent is present) | `Seo` |   |
| `[].seo.noIndex` (Required when parent is present) | `boolean` | Ask search engines not to index the resource's own page — for a package, its checkout page (robots "noindex"). The page stays reachable by direct link. |
| `[].seo.noFollow` (Required when parent is present) | `boolean` | Ask search engines not to follow links on the resource's own page — for a package, its checkout page (robots "nofollow"). |
| `[].onboardingWelcomeRedirectCTAText` (Required when parent is present) | `Translation` | Can be null |
| `[].onboardingWelcomeRedirectCTAText.en` (Required when parent is present) | `string` |   |
| `[].onboardingWelcomeRedirectCTAText.no` (Required when parent is present) | `string` |   |
| `[].onboardingWelcomeRedirectCTAText.sv` | `string` |   |
| `[].onboardingWelcomeRedirectCTAText.da` | `string` |   |
| `[].onboardingWelcomeRedirectCTAText.key` | `string` |   |
| `[].customPeriodText` (Required when parent is present) | `Translation` | Can be null |
| `[].customPeriodText.en` (Required when parent is present) | `string` |   |
| `[].customPeriodText.no` (Required when parent is present) | `string` |   |
| `[].customPeriodText.sv` | `string` |   |
| `[].customPeriodText.da` | `string` |   |
| `[].customPeriodText.key` | `string` |   |
| `[].subscriptionCount` (Required when parent is present) | `number` |   |
| `[].products` (Required when parent is present) | `array of PackProduct` | Can be null |
| `[].products[].productId` (Required when parent is present) | `number` |   |
| `[].products[].name` (Required when parent is present) | `string` |   |
| `[].products[].price` (Required when parent is present) | `number` |   |
| `[].products[].currency` (Required when parent is present) | `string` |   |
| `[].products[].tax` (Required when parent is present) | `number` |   |
| `[].products[].basePrice` (Required when parent is present) | `number` |   |
| `[].products[].recurringPrice` (Required when parent is present) | `number` |   |
| `[].products[].isOptional` (Required when parent is present) | `boolean` |   |
| `[].products[].productCategory` (Required when parent is present) | `string` | Allowed values: `"digital_subscription"`, `"physical_subscription"`, `"physical"`, `"event_ticket"`, `"PHYSICAL_PRODUCT"` |
| `[].products[].circulationType` | `CIRCULATION_TYPE` | Allowed values: `"subscription"`, `"single_copy"` · Can be null |
| `[].products[].properties` (Required when parent is present) | `OptionalProductProperties` | Can be null |
| `[].products[].properties.isRequired` (Required when parent is present) | `boolean` |   |
| `[].products[].properties.quantityRange` (Required when parent is present) | `number` |   |
| `[].products[].recurringProperties` (Required when parent is present) | `OptionalProductProperties` | Can be null |
| `[].products[].recurringProperties.isRequired` (Required when parent is present) | `boolean` |   |
| `[].products[].recurringProperties.quantityRange` (Required when parent is present) | `number` |   |
| `[].products[].shippingCharges` (Required when parent is present) | `array of ShippingCharge` |   |
| `[].products[].shippingCharges[].country` (Required when parent is present) | `string` |   |
| `[].products[].shippingCharges[].charge` (Required when parent is present) | `number` |   |
| `[].products[].description` (Required when parent is present) | `string` |   |
| `[].price` (Required when parent is present) | `number` | Default: `0` |
| `[].recurringPrice` (Required when parent is present) | `number` |   |
| `[].isAvailableOnMyPage` (Required when parent is present) | `boolean` |   |
| `[].isAvailableForManualOrderViaAdmin` (Required when parent is present) | `boolean` |   |
| `[].customInputFields` (Required when parent is present) | `CustomInputFields` |   |
| `[].customInputFields.memberType` (Required when parent is present) | `boolean` |   |
| `[].customInputFields.invoiceAddress` (Required when parent is present) | `boolean` |   |
| `[].customInputFields.city` (Required when parent is present) | `boolean` |   |
| `[].salesTitle` (Required when parent is present) | `string` |   |
| `[].uuid` (Required when parent is present) | `string` |   |
| `[].subscriptionPlanId` (Required when parent is present) | `number` |   |
| `[].slug` (Required when parent is present) | `string` |   |
| `[].image` (Required when parent is present) | `string` |   |
| `[].name` (Required when parent is present) | `string` |   |
| `[].description` (Required when parent is present) | `object` |   |
| `[].billingPeriod` (Required when parent is present) | `string` | Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `[].billingPeriodUnit` (Required when parent is present) | `string` | Allowed values: `"day"`, `"week"`, `"month"`, `"year"` |
| `[].billingPeriodFrequency` (Required when parent is present) | `number` |   |
| `[].status` (Required when parent is present) | `string` | Allowed values: `"draft"`, `"published"`, `"archived"` |
| `[].isAvailableViaSlug` (Required when parent is present) | `boolean` |   |
| `[].allowSameSubscriptionChange` (Required when parent is present) | `boolean` |   |
| `[].allowDifferentSubscriptionSwitch` (Required when parent is present) | `boolean` |   |
| `[].tenantId` (Required when parent is present) | `number` |   |
| `[].orderCtaLabel` (Required when parent is present) | `Translation` |   |
| `[].orderCtaLabel.en` (Required when parent is present) | `string` |   |
| `[].orderCtaLabel.no` (Required when parent is present) | `string` |   |
| `[].orderCtaLabel.sv` | `string` |   |
| `[].orderCtaLabel.da` | `string` |   |
| `[].orderCtaLabel.key` | `string` |   |
| `[].introPeriodFixedEndDate` (Required when parent is present) | `string (date-time)` |   |
| `[].packageProducts` (Required when parent is present) | `array of PackageProduct` | Nested fields omitted: field limit. |
| `[].subscriptionPlan` (Required when parent is present) | `SubscriptionPlan` | Nested fields omitted: field limit. |
| `[].payments` (Required when parent is present) | `array of Payment` | Nested fields omitted: field limit. |
| `[].memberPackages` (Required when parent is present) | `array of MemberPackage` | Nested fields omitted: field limit. |
| `[].id` (Required when parent is present) | `number` |   |
| `[].createdAt` (Required when parent is present) | `string (date-time)` |   |
| `[].updatedAt` (Required when parent is present) | `string (date-time)` |   |
| `[].deletedAt` (Required when parent is present) | `string (date-time)` |   |
| `[].metaData` (Required when parent is present) | `object` |   |

#### 400

Content type: `application/json` · `ErrorResponse`

Query validation failed; field codes in errors\[\]

Same fields as [Get all packages of the tenant (400)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages/all \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
[
  {
    "paymentProviders": [],
    "repeatPurchaseControl": "allow",
    "repeatPurchaseCooldownDays": 0,
    "displayOrder": 0,
    "seo": {},
    "onboardingWelcomeRedirectCTAText": {},
    "customPeriodText": {},
    "subscriptionCount": 0,
    "products": [],
    "price": 0,
    "recurringPrice": 0,
    "isAvailableOnMyPage": true,
    "isAvailableForManualOrderViaAdmin": true,
    "customInputFields": {},
    "salesTitle": "string",
    "uuid": "string",
    "subscriptionPlanId": 0,
    "slug": "string",
    "image": "string",
    "name": "string",
    "description": {},
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "status": "draft",
    "isAvailableViaSlug": true,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "tenantId": 0,
    "orderCtaLabel": {},
    "introPeriodFixedEndDate": "2019-08-24T14:15:22Z",
    "packageProducts": [],
    "subscriptionPlan": {
      "paymentProviders": [],
      "entityTags": [],
      "subscriptionPlanProducts": [],
      "packages": [],
      "memberPackages": [],
      "metaData": {}
    },
    "payments": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  }
]
```

<a id="get-api-v1-product-packages-id"></a>
## Get a package by id

`GET /api/v1/product-packages/{id}`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `id` (Required) | path | `number` |   |

### Responses

#### 200

Content type: `application/json` · `PackageResponse`

Same fields as [Create a new package (201)](https://www.subrite.no/developers/product-package?md=true#post-api-v1-product-packages).

#### 400

Content type: `application/json` · `ErrorResponse`

The id is not an integer

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 404

Content type: `application/json` · `ErrorResponse`

packageNotFound

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"packageNotFound"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/{id}' \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
{
  "paymentProviders": [
    "stripe"
  ],
  "repeatPurchaseControl": "allow",
  "repeatPurchaseCooldownDays": 0,
  "displayOrder": 0,
  "seo": {
    "noIndex": true,
    "noFollow": true
  },
  "onboardingWelcomeRedirectCTAText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "customPeriodText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "subscriptionCount": 0,
  "products": [
    {
      "shippingCharges": []
    }
  ],
  "price": 0,
  "recurringPrice": 0,
  "isAvailableOnMyPage": true,
  "isAvailableForManualOrderViaAdmin": true,
  "customInputFields": {
    "memberType": true,
    "invoiceAddress": true,
    "city": true
  },
  "salesTitle": "string",
  "uuid": "string",
  "subscriptionPlanId": 0,
  "slug": "string",
  "image": "string",
  "name": "string",
  "description": {},
  "billingPeriod": "monthly",
  "billingPeriodUnit": "day",
  "billingPeriodFrequency": 0,
  "status": "draft",
  "isAvailableViaSlug": true,
  "allowSameSubscriptionChange": true,
  "allowDifferentSubscriptionSwitch": true,
  "tenantId": 0,
  "orderCtaLabel": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "introPeriodFixedEndDate": "2019-08-24T14:15:22Z",
  "packageProducts": [
    {
      "metaData": {}
    }
  ],
  "subscriptionPlan": {
    "paymentProviders": [],
    "name": "string",
    "uuid": "string",
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "autoRenew": true,
    "status": "draft",
    "tenantId": 0,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "allowAdminSameSubscriptionChange": true,
    "allowAdminDifferentSubscriptionSwitch": true,
    "enableGiftSubscription": true,
    "allowFutureStartDate": true,
    "showAsOptionOnSubscriptionSwitch": true,
    "showAsOptionOnAdminSubscriptionSwitch": true,
    "offerSwitchOnCheckout": true,
    "tenant": {
      "additionalFeatures": [],
      "disabledFeatures": [],
      "taxRates": [],
      "products": [],
      "users": [],
      "members": [],
      "roles": [],
      "subscriptionPlans": [],
      "packages": [],
      "invoices": [],
      "orders": [],
      "paymentProviders": [],
      "newslettersProviderConfig": [],
      "paymentProviderConfigs": [],
      "oidcClients": [],
      "oauthProviders": [],
      "activityLogs": [],
      "m2m_api_clients": [],
      "customProperties": [],
      "consents": [],
      "communicationTemplates": [],
      "additionalHostnames": [],
      "exportHistory": [],
      "arReportHistory": [],
      "mypageCardsSettings": [],
      "webhooks": [],
      "customOrders": [],
      "customOrderSources": [],
      "brandKits": [],
      "communicationReceivers": [],
      "metaData": {}
    },
    "entityTags": [],
    "subscriptionPlanProducts": [],
    "packages": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "payments": [
    {
      "metaData": {}
    }
  ],
  "memberPackages": [
    {
      "memberPackageProducts": [],
      "orders": [],
      "changes": [],
      "histories": [],
      "metaData": {}
    }
  ],
  "id": 0,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "deletedAt": "2019-08-24T14:15:22Z",
  "metaData": {}
}
```

<a id="delete-api-v1-product-packages-id"></a>
## Delete a package

`DELETE /api/v1/product-packages/{id}`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `id` (Required) | path | `number` |   |

### Responses

#### 200

#### 400

Content type: `application/json` · `ErrorResponse`

The id is not an integer, members hold subscriptions to the package, or a tenant preference still points at it

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"`, `"packageIsActiveAsSubscriptions"`, `"packageIsReferencedInSettings"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 404

Content type: `application/json` · `ErrorResponse`

packageNotFound

Same fields as [Get a package by id (404)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages-id).

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/{id}' \
  --request DELETE \
  --header 'Authorization: Bearer <token>'
```

<a id="patch-api-v1-product-packages-id"></a>
## Update a package

`PATCH /api/v1/product-packages/{id}`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `id` (Required) | path | `number` |   |

### Request body

Content type: `multipart/form-data` · Required · `UpdatePackageDto`

| Name | Type | Description |
| --- | --- | --- |
| `salesTitle` | `string` |   |
| `slug` | `string` |   |
| `subscriptionPlanId` | `number` | `minimum`: `1` |
| `name` | `string` |   |
| `paymentProviders` | `array of PAYMENT_PROVIDER` | Allowed values: `"stripe"`, `"vipps"`, `"external"`, `"nets"`, `"efaktura-avtalegiro-ehf"`, `"swedbankpay"` · `minItems`: `1` |
| `description` | `string` |   |
| `image` | `file` |   |
| `imageUrl` | `string (uri)` | Public URL of a file in the Assets library to use as the package image, instead of uploading bytes. The file is referenced rather than copied. |
| `billingPeriod` | `string` | Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `billingPeriodUnit` | `string` | Allowed values: `"day"`, `"week"`, `"month"`, `"year"` |
| `billingPeriodFrequency` | `number` | `minimum`: `1` |
| `status` | `string` | Allowed values: `"draft"`, `"published"`, `"archived"` |
| `isAvailableOnMyPage` | `boolean` |   |
| `isAvailableViaSlug` | `boolean` |   |
| `isAvailableForManualOrderViaAdmin` | `boolean` |   |
| `onboardingWelcomeRedirectCTAText` | `Translation` |   |
| `onboardingWelcomeRedirectCTAText.en` (Required when parent is present) | `string` |   |
| `onboardingWelcomeRedirectCTAText.no` (Required when parent is present) | `string` |   |
| `onboardingWelcomeRedirectCTAText.sv` | `string` |   |
| `onboardingWelcomeRedirectCTAText.da` | `string` |   |
| `onboardingWelcomeRedirectCTAText.key` | `string` |   |
| `customPeriodText` | `Translation` |   |
| `customPeriodText.en` (Required when parent is present) | `string` |   |
| `customPeriodText.no` (Required when parent is present) | `string` |   |
| `customPeriodText.sv` | `string` |   |
| `customPeriodText.da` | `string` |   |
| `customPeriodText.key` | `string` |   |
| `orderCtaLabel` | `Translation` |   |
| `orderCtaLabel.en` (Required when parent is present) | `string` |   |
| `orderCtaLabel.no` (Required when parent is present) | `string` |   |
| `orderCtaLabel.sv` | `string` |   |
| `orderCtaLabel.da` | `string` |   |
| `orderCtaLabel.key` | `string` |   |
| `seo` | `Seo` |   |
| `seo.noIndex` (Required when parent is present) | `boolean` | Ask search engines not to index the resource's own page — for a package, its checkout page (robots "noindex"). The page stays reachable by direct link. |
| `seo.noFollow` (Required when parent is present) | `boolean` | Ask search engines not to follow links on the resource's own page — for a package, its checkout page (robots "nofollow"). |
| `products` | `array of PackageProductDto` | `minItems`: `1` |
| `products[].productId` (Required when parent is present) | `number` | `minimum`: `1` |
| `products[].price` (Required when parent is present) | `number` | `minimum`: `0` |
| `products[].properties` | `OptionalProductProperties` |   |
| `products[].properties.isRequired` (Required when parent is present) | `boolean` |   |
| `products[].properties.quantityRange` (Required when parent is present) | `number` |   |
| `introPeriodFixedEndDate` | `string (date-time)` |   |
| `repeatPurchaseControl` | `RepeatPurchaseControl` | Allowed values: `"allow"`, `"warning"`, `"block_active"`, `"block_forever"`, `"cooldown"` |
| `repeatPurchaseCooldownDays` | `number` | `minimum`: `1` |
| `imagePreview` | `string` |   |
| `previousImageUrl` | `string` |   |

### Responses

#### 200

Content type: `application/json` · `PackageResponse`

Same fields as [Create a new package (201)](https://www.subrite.no/developers/product-package?md=true#post-api-v1-product-packages).

#### 400

Content type: `application/json` · `ErrorResponse`

Body validation failed, the id is not an integer, a product id is unknown, or the intro-period/billing-period combination is invalid; field codes in errors\[\]

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"`, `"internalServerError"`, `"invalidProducts"`, `"setEitherIntroPeriodFixedEndDateOrBillingPeriod"`, `"introPeriodFixedEndDateAndBillingPeriodCannotCoexist"`, `"missingUnitOrFrequencyForCustomBillingPeriod"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 404

Content type: `application/json` · `ErrorResponse`

packageNotFound

Same fields as [Get a package by id (404)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages-id).

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 413

fileSizeExceeded

#### 415

invalidFileType

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 502

Content type: `application/json` · `ErrorResponse`

The new image could not be stored; nothing was saved

Same fields as [Create a new package (502)](https://www.subrite.no/developers/product-package?md=true#post-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "packageImageUploadFailed",
  "message": "string",
  "errors": [
    {}
  ]
}
```

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/{id}' \
  --request PATCH \
  --header 'Authorization: Bearer <token>' \
  --form 'image=@<file>'
```

### Example response

200 · `application/json`

```json
{
  "paymentProviders": [
    "stripe"
  ],
  "repeatPurchaseControl": "allow",
  "repeatPurchaseCooldownDays": 0,
  "displayOrder": 0,
  "seo": {
    "noIndex": true,
    "noFollow": true
  },
  "onboardingWelcomeRedirectCTAText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "customPeriodText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "subscriptionCount": 0,
  "products": [
    {
      "shippingCharges": []
    }
  ],
  "price": 0,
  "recurringPrice": 0,
  "isAvailableOnMyPage": true,
  "isAvailableForManualOrderViaAdmin": true,
  "customInputFields": {
    "memberType": true,
    "invoiceAddress": true,
    "city": true
  },
  "salesTitle": "string",
  "uuid": "string",
  "subscriptionPlanId": 0,
  "slug": "string",
  "image": "string",
  "name": "string",
  "description": {},
  "billingPeriod": "monthly",
  "billingPeriodUnit": "day",
  "billingPeriodFrequency": 0,
  "status": "draft",
  "isAvailableViaSlug": true,
  "allowSameSubscriptionChange": true,
  "allowDifferentSubscriptionSwitch": true,
  "tenantId": 0,
  "orderCtaLabel": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "introPeriodFixedEndDate": "2019-08-24T14:15:22Z",
  "packageProducts": [
    {
      "metaData": {}
    }
  ],
  "subscriptionPlan": {
    "paymentProviders": [],
    "name": "string",
    "uuid": "string",
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "autoRenew": true,
    "status": "draft",
    "tenantId": 0,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "allowAdminSameSubscriptionChange": true,
    "allowAdminDifferentSubscriptionSwitch": true,
    "enableGiftSubscription": true,
    "allowFutureStartDate": true,
    "showAsOptionOnSubscriptionSwitch": true,
    "showAsOptionOnAdminSubscriptionSwitch": true,
    "offerSwitchOnCheckout": true,
    "tenant": {
      "additionalFeatures": [],
      "disabledFeatures": [],
      "taxRates": [],
      "products": [],
      "users": [],
      "members": [],
      "roles": [],
      "subscriptionPlans": [],
      "packages": [],
      "invoices": [],
      "orders": [],
      "paymentProviders": [],
      "newslettersProviderConfig": [],
      "paymentProviderConfigs": [],
      "oidcClients": [],
      "oauthProviders": [],
      "activityLogs": [],
      "m2m_api_clients": [],
      "customProperties": [],
      "consents": [],
      "communicationTemplates": [],
      "additionalHostnames": [],
      "exportHistory": [],
      "arReportHistory": [],
      "mypageCardsSettings": [],
      "webhooks": [],
      "customOrders": [],
      "customOrderSources": [],
      "brandKits": [],
      "communicationReceivers": [],
      "metaData": {}
    },
    "entityTags": [],
    "subscriptionPlanProducts": [],
    "packages": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "payments": [
    {
      "metaData": {}
    }
  ],
  "memberPackages": [
    {
      "memberPackageProducts": [],
      "orders": [],
      "changes": [],
      "histories": [],
      "metaData": {}
    }
  ],
  "id": 0,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "deletedAt": "2019-08-24T14:15:22Z",
  "metaData": {}
}
```

<a id="get-api-v1-product-packages-slug-tenantid-slug"></a>
## Get a package by slug

`GET /api/v1/product-packages/slug/{tenantId}/{slug}`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `tenantId` (Required) | path | `number` |   |
| `slug` (Required) | path | `string` |   |

### Responses

#### 200

Content type: `application/json` · `PackageResponse`

Same fields as [Create a new package (201)](https://www.subrite.no/developers/product-package?md=true#post-api-v1-product-packages).

#### 400

Content type: `application/json` · `ErrorResponse`

The tenantId is not an integer, the slug is malformed, or the campaign has ended

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"`, `"campaignIsOver"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

Content type: `application/json` · `ErrorResponse`

unauthorized

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 404

Content type: `application/json` · `ErrorResponse`

No published package has that slug in the tenant, or it is not offered via its slug

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"packageNotFound"`, `"notAvailableViaSlug"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/slug/{tenantId}/{slug}' \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
{
  "paymentProviders": [
    "stripe"
  ],
  "repeatPurchaseControl": "allow",
  "repeatPurchaseCooldownDays": 0,
  "displayOrder": 0,
  "seo": {
    "noIndex": true,
    "noFollow": true
  },
  "onboardingWelcomeRedirectCTAText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "customPeriodText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "subscriptionCount": 0,
  "products": [
    {
      "shippingCharges": []
    }
  ],
  "price": 0,
  "recurringPrice": 0,
  "isAvailableOnMyPage": true,
  "isAvailableForManualOrderViaAdmin": true,
  "customInputFields": {
    "memberType": true,
    "invoiceAddress": true,
    "city": true
  },
  "salesTitle": "string",
  "uuid": "string",
  "subscriptionPlanId": 0,
  "slug": "string",
  "image": "string",
  "name": "string",
  "description": {},
  "billingPeriod": "monthly",
  "billingPeriodUnit": "day",
  "billingPeriodFrequency": 0,
  "status": "draft",
  "isAvailableViaSlug": true,
  "allowSameSubscriptionChange": true,
  "allowDifferentSubscriptionSwitch": true,
  "tenantId": 0,
  "orderCtaLabel": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "introPeriodFixedEndDate": "2019-08-24T14:15:22Z",
  "packageProducts": [
    {
      "metaData": {}
    }
  ],
  "subscriptionPlan": {
    "paymentProviders": [],
    "name": "string",
    "uuid": "string",
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "autoRenew": true,
    "status": "draft",
    "tenantId": 0,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "allowAdminSameSubscriptionChange": true,
    "allowAdminDifferentSubscriptionSwitch": true,
    "enableGiftSubscription": true,
    "allowFutureStartDate": true,
    "showAsOptionOnSubscriptionSwitch": true,
    "showAsOptionOnAdminSubscriptionSwitch": true,
    "offerSwitchOnCheckout": true,
    "tenant": {
      "additionalFeatures": [],
      "disabledFeatures": [],
      "taxRates": [],
      "products": [],
      "users": [],
      "members": [],
      "roles": [],
      "subscriptionPlans": [],
      "packages": [],
      "invoices": [],
      "orders": [],
      "paymentProviders": [],
      "newslettersProviderConfig": [],
      "paymentProviderConfigs": [],
      "oidcClients": [],
      "oauthProviders": [],
      "activityLogs": [],
      "m2m_api_clients": [],
      "customProperties": [],
      "consents": [],
      "communicationTemplates": [],
      "additionalHostnames": [],
      "exportHistory": [],
      "arReportHistory": [],
      "mypageCardsSettings": [],
      "webhooks": [],
      "customOrders": [],
      "customOrderSources": [],
      "brandKits": [],
      "communicationReceivers": [],
      "metaData": {}
    },
    "entityTags": [],
    "subscriptionPlanProducts": [],
    "packages": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "payments": [
    {
      "metaData": {}
    }
  ],
  "memberPackages": [
    {
      "memberPackageProducts": [],
      "orders": [],
      "changes": [],
      "histories": [],
      "metaData": {}
    }
  ],
  "id": 0,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "deletedAt": "2019-08-24T14:15:22Z",
  "metaData": {}
}
```

<a id="get-api-v1-product-packages-id-tenantid-id-slug"></a>
## Get a package slug by id

`GET /api/v1/product-packages/id/{tenantId}/{id}/slug`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `tenantId` (Required) | path | `number` |   |
| `id` (Required) | path | `number` |   |

### Responses

#### 200

Content type: `application/json` · `PackageSlugResponseDto`

| Name | Type | Description |
| --- | --- | --- |
| `slug` (Required) | `string` |   |

#### 400

Content type: `application/json` · `ErrorResponse`

A path segment is not an integer

Same fields as [Get a package by id (400)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages-id).

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

Content type: `application/json` · `ErrorResponse`

unauthorized

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 404

Content type: `application/json` · `ErrorResponse`

packageNotFound

Same fields as [Get a package by id (404)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages-id).

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/id/{tenantId}/{id}/slug' \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
{
  "slug": "string"
}
```

<a id="patch-api-v1-product-packages-display-order-all"></a>
## Update the mypage display order of packages for a tenant

`PATCH /api/v1/product-packages/display-order/all`

**Authentication:** Bearer token (JWT)

### Request body

Content type: `application/json` · Required · `array of UpdatePackageDisplayOrderRequestDto`

| Name | Type | Description |
| --- | --- | --- |
| `[].id` (Required when parent is present) | `number` |   |
| `[].displayOrder` (Required when parent is present) | `number` | The order in which the package should appear on mypage · `minimum`: `0` |

**Example request body**

`application/json`

```json
[
  {
    "id": 0,
    "displayOrder": 0
  }
]
```

### Responses

#### 200

#### 400

Content type: `application/json` · `ErrorResponse`

Body validation failed, or a package id does not exist in this tenant; field codes in errors\[\]

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"`, `"internalServerError"`, `"invalidPackages"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages/display-order/all \
  --request PATCH \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '[
  {
    "id": 0,
    "displayOrder": 0
  }
]'
```

<a id="post-api-v1-product-packages-price-by-quantity"></a>
## Get introductory & recurring price by quantity of optional products

`POST /api/v1/product-packages/price-by-quantity`

**Authentication:** Bearer token (JWT)

### Request body

Content type: `application/json` · Required · `PriceByQuantityDto`

| Name | Type | Description |
| --- | --- | --- |
| `packageId` (Required) | `number` | `minimum`: `1` |
| `products` (Required) | `array of OptionalProductWithQuantity` |   |
| `products[].productId` (Required when parent is present) | `number` | `minimum`: `1` |
| `products[].quantity` (Required when parent is present) | `number` | `minimum`: `1` |
| `products[].shippingCountry` | `string` | `maxLength`: `64` |
| `products[].manualPrice` | `number` |   |

### Responses

#### 201

Content type: `application/json` · `PackageResponse`

Same fields as [Create a new package (201)](https://www.subrite.no/developers/product-package?md=true#post-api-v1-product-packages).

#### 400

Content type: `application/json` · `ErrorResponse`

Body validation failed; field codes in errors\[\]

Same fields as [Get all packages of the tenant (400)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

Content type: `application/json` · `ErrorResponse`

unauthorized

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 404

Content type: `application/json` · `ErrorResponse`

packageNotFound

Same fields as [Get a package by id (404)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages-id).

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages/price-by-quantity \
  --request POST \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "packageId": 1,
  "products": [
    {}
  ]
}'
```

### Example response

201 · `application/json`

```json
{
  "paymentProviders": [
    "stripe"
  ],
  "repeatPurchaseControl": "allow",
  "repeatPurchaseCooldownDays": 0,
  "displayOrder": 0,
  "seo": {
    "noIndex": true,
    "noFollow": true
  },
  "onboardingWelcomeRedirectCTAText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "customPeriodText": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "subscriptionCount": 0,
  "products": [
    {
      "shippingCharges": []
    }
  ],
  "price": 0,
  "recurringPrice": 0,
  "isAvailableOnMyPage": true,
  "isAvailableForManualOrderViaAdmin": true,
  "customInputFields": {
    "memberType": true,
    "invoiceAddress": true,
    "city": true
  },
  "salesTitle": "string",
  "uuid": "string",
  "subscriptionPlanId": 0,
  "slug": "string",
  "image": "string",
  "name": "string",
  "description": {},
  "billingPeriod": "monthly",
  "billingPeriodUnit": "day",
  "billingPeriodFrequency": 0,
  "status": "draft",
  "isAvailableViaSlug": true,
  "allowSameSubscriptionChange": true,
  "allowDifferentSubscriptionSwitch": true,
  "tenantId": 0,
  "orderCtaLabel": {
    "en": "string",
    "no": "string",
    "sv": "string",
    "da": "string",
    "key": "string"
  },
  "introPeriodFixedEndDate": "2019-08-24T14:15:22Z",
  "packageProducts": [
    {
      "metaData": {}
    }
  ],
  "subscriptionPlan": {
    "paymentProviders": [],
    "name": "string",
    "uuid": "string",
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "autoRenew": true,
    "status": "draft",
    "tenantId": 0,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "allowAdminSameSubscriptionChange": true,
    "allowAdminDifferentSubscriptionSwitch": true,
    "enableGiftSubscription": true,
    "allowFutureStartDate": true,
    "showAsOptionOnSubscriptionSwitch": true,
    "showAsOptionOnAdminSubscriptionSwitch": true,
    "offerSwitchOnCheckout": true,
    "tenant": {
      "additionalFeatures": [],
      "disabledFeatures": [],
      "taxRates": [],
      "products": [],
      "users": [],
      "members": [],
      "roles": [],
      "subscriptionPlans": [],
      "packages": [],
      "invoices": [],
      "orders": [],
      "paymentProviders": [],
      "newslettersProviderConfig": [],
      "paymentProviderConfigs": [],
      "oidcClients": [],
      "oauthProviders": [],
      "activityLogs": [],
      "m2m_api_clients": [],
      "customProperties": [],
      "consents": [],
      "communicationTemplates": [],
      "additionalHostnames": [],
      "exportHistory": [],
      "arReportHistory": [],
      "mypageCardsSettings": [],
      "webhooks": [],
      "customOrders": [],
      "customOrderSources": [],
      "brandKits": [],
      "communicationReceivers": [],
      "metaData": {}
    },
    "entityTags": [],
    "subscriptionPlanProducts": [],
    "packages": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "payments": [
    {
      "metaData": {}
    }
  ],
  "memberPackages": [
    {
      "memberPackageProducts": [],
      "orders": [],
      "changes": [],
      "histories": [],
      "metaData": {}
    }
  ],
  "id": 0,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "deletedAt": "2019-08-24T14:15:22Z",
  "metaData": {}
}
```

<a id="post-api-v1-product-packages-subscribe"></a>
## Create a subscription for pre-puchased package

`POST /api/v1/product-packages/subscribe`

**Authentication:** Bearer token (JWT)

### Request body

Content type: `application/json` · Required · `PrePurchasePackageSubscriptionDto`

| Name | Type | Description |
| --- | --- | --- |
| `packageId` (Required) | `number` | `minimum`: `1` |
| `optionalProducts` | `array of OptionalProductWithQuantity` |   |
| `optionalProducts[].productId` (Required when parent is present) | `number` | `minimum`: `1` |
| `optionalProducts[].quantity` (Required when parent is present) | `number` | `minimum`: `1` |
| `optionalProducts[].shippingCountry` | `string` | `maxLength`: `64` |
| `optionalProducts[].manualPrice` | `number` |   |
| `paymentDate` | `string (date-time)` |   |
| `memberId` (Required) | `string (uuid)` |   |
| `reference` (Required) | `string` | `maxLength`: `255` |

**Example request body**

`application/json`

```json
{
  "packageId": 1,
  "paymentDate": "2019-08-24T14:15:22Z",
  "memberId": "92983ab9-49c8-444b-85ae-6e40402cf72e",
  "reference": "string"
}
```

### Responses

#### 201

Content type: `application/json` · `PrePurchasePackageResponseDto`

| Name | Type | Description |
| --- | --- | --- |
| `memberId` (Required) | `string` |   |
| `packageId` (Required) | `number` |   |
| `subscriptionPlanId` (Required) | `number` |   |
| `recurringPrice` (Required) | `number` |   |
| `hasCustomPrice` (Required) | `boolean` |   |
| `currentPrice` (Required) | `number` |   |
| `status` (Required) | `string` | Allowed values: `"active"`, `"inactive"`, `"pending"`, `"paused"`, `"stopped"`, `"expired"`, `"waiting_for_activation"` |
| `autoRenew` (Required) | `boolean` |   |
| `nextRenewal` (Required) | `string (date-time)` |   |
| `renewalAnchorDate` (Required) | `string (date-time)` |   |
| `currentPeriodStart` (Required) | `string (date-time)` |   |
| `forcedStopDate` (Required) | `string (date-time)` |   |
| `cancelledAt` (Required) | `string (date-time)` |   |
| `isCustomized` (Required) | `boolean` |   |
| `paymentProvider` (Required) | `string` | Allowed values: `"stripe"`, `"vipps"`, `"external"`, `"nets"`, `"efaktura-avtalegiro-ehf"`, `"swedbankpay"` |
| `reference` (Required) | `string` |   |
| `lastActiveAt` (Required) | `string (date-time)` |   |
| `isOnIntroPeriod` (Required) | `boolean` |   |
| `nextOrderDate` (Required) | `string (date-time)` |   |
| `scheduledActivationDate` (Required) | `string (date-time)` | Can be null |
| `package` (Required) | `Package` |   |
| `package.paymentProviders` (Required) | `array of PAYMENT_PROVIDER` | Allowed values: `"stripe"`, `"vipps"`, `"external"`, `"nets"`, `"efaktura-avtalegiro-ehf"`, `"swedbankpay"` |
| `package.repeatPurchaseControl` (Required) | `RepeatPurchaseControl` | Allowed values: `"allow"`, `"warning"`, `"block_active"`, `"block_forever"`, `"cooldown"` |
| `package.repeatPurchaseCooldownDays` | `number` | Can be null |
| `package.displayOrder` | `number` | Can be null |
| `package.seo` | `Seo` | Can be null |
| `package.seo.noIndex` (Required when parent is present) | `boolean` | Ask search engines not to index the resource's own page — for a package, its checkout page (robots "noindex"). The page stays reachable by direct link. |
| `package.seo.noFollow` (Required when parent is present) | `boolean` | Ask search engines not to follow links on the resource's own page — for a package, its checkout page (robots "nofollow"). |
| `package.salesTitle` (Required) | `string` |   |
| `package.uuid` (Required) | `string` |   |
| `package.subscriptionPlanId` (Required) | `number` |   |
| `package.slug` (Required) | `string` |   |
| `package.image` (Required) | `string` |   |
| `package.name` (Required) | `string` |   |
| `package.description` (Required) | `object` |   |
| `package.billingPeriod` (Required) | `string` | Allowed values: `"monthly"`, `"thirty_days"`, `"quarterly"`, `"half_yearly"`, `"yearly"`, `"custom"` |
| `package.billingPeriodUnit` (Required) | `string` | Allowed values: `"day"`, `"week"`, `"month"`, `"year"` |
| `package.billingPeriodFrequency` (Required) | `number` |   |
| `package.status` (Required) | `string` | Allowed values: `"draft"`, `"published"`, `"archived"` |
| `package.isAvailableOnMyPage` (Required) | `boolean` |   |
| `package.isAvailableViaSlug` (Required) | `boolean` |   |
| `package.isAvailableForManualOrderViaAdmin` (Required) | `boolean` |   |
| `package.allowSameSubscriptionChange` (Required) | `boolean` |   |
| `package.allowDifferentSubscriptionSwitch` (Required) | `boolean` |   |
| `package.tenantId` (Required) | `number` |   |
| `package.onboardingWelcomeRedirectCTAText` (Required) | `Translation` | Nested fields omitted: field limit. |
| `package.customPeriodText` (Required) | `Translation` | Nested fields omitted: field limit. |
| `package.orderCtaLabel` (Required) | `Translation` | Nested fields omitted: field limit. |
| `package.introPeriodFixedEndDate` (Required) | `string (date-time)` |   |
| `package.packageProducts` (Required) | `array of PackageProduct` | Nested fields omitted: field limit. |
| `package.subscriptionPlan` (Required) | `SubscriptionPlan` | Nested fields omitted: field limit. |
| `package.payments` (Required) | `array of Payment` | Nested fields omitted: field limit. |
| `package.memberPackages` (Required) | `array of MemberPackage` | Nested fields omitted: field limit. |
| `package.id` (Required) | `number` |   |
| `package.createdAt` (Required) | `string (date-time)` |   |
| `package.updatedAt` (Required) | `string (date-time)` |   |
| `package.deletedAt` (Required) | `string (date-time)` |   |
| `package.metaData` (Required) | `object` |   |
| `subscriptionPlan` (Required) | `SubscriptionPlan` | Nested fields omitted: field limit. |
| `member` (Required) | `Member` | Nested fields omitted: field limit. |
| `memberPackageProducts` (Required) | `array of MemberPackageProduct` | Nested fields omitted: field limit. |
| `orders` (Required) | `array of Order` | Nested fields omitted: field limit. |
| `memberPackageProviderPayment` (Required) | `MemberPackageProviderPayment` | Nested fields omitted: field limit. |
| `changes` (Required) | `array of MemberPackageChange` | Nested fields omitted: field limit. |
| `histories` (Required) | `array of MemberPackageHistory` | Nested fields omitted: field limit. |
| `tenantId` (Required) | `number` |   |
| `tenant` (Required) | `Tenant` | Nested fields omitted: field limit. |
| `id` (Required) | `number` |   |
| `createdAt` (Required) | `string (date-time)` |   |
| `updatedAt` (Required) | `string (date-time)` |   |
| `deletedAt` (Required) | `string (date-time)` |   |
| `metaData` (Required) | `object` |   |
| `planName` (Required) | `string` |   |
| `packageName` (Required) | `string` |   |
| `email` (Required) | `string` |   |
| `fullName` (Required) | `string` |   |
| `paymentDate` (Required) | `string` |   |
| `paymentMethod` (Required) | `string` |   |

#### 400

Content type: `application/json` · `ErrorResponse`

Body validation failed; field codes in errors\[\]

Same fields as [Get all packages of the tenant (400)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

unauthorized

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 404

Content type: `application/json` · `ErrorResponse`

No such package, or no member with that id in this tenant

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"packageNotFound"`, `"memberNotFound"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl https://api.subrite.no/api/v1/product-packages/subscribe \
  --request POST \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "packageId": 1,
  "optionalProducts": [
    {}
  ],
  "paymentDate": "2019-08-24T14:15:22Z",
  "memberId": "92983ab9-49c8-444b-85ae-6e40402cf72e",
  "reference": "string"
}'
```

### Example response

201 · `application/json`

```json
{
  "memberId": "string",
  "packageId": 0,
  "subscriptionPlanId": 0,
  "recurringPrice": 0,
  "hasCustomPrice": true,
  "currentPrice": 0,
  "status": "active",
  "autoRenew": true,
  "nextRenewal": "2019-08-24T14:15:22Z",
  "renewalAnchorDate": "2019-08-24T14:15:22Z",
  "currentPeriodStart": "2019-08-24T14:15:22Z",
  "forcedStopDate": "2019-08-24T14:15:22Z",
  "cancelledAt": "2019-08-24T14:15:22Z",
  "isCustomized": true,
  "paymentProvider": "stripe",
  "reference": "string",
  "lastActiveAt": "2019-08-24T14:15:22Z",
  "isOnIntroPeriod": true,
  "nextOrderDate": "2019-08-24T14:15:22Z",
  "scheduledActivationDate": "2019-08-24T14:15:22Z",
  "package": {
    "paymentProviders": [],
    "repeatPurchaseControl": "allow",
    "repeatPurchaseCooldownDays": 0,
    "displayOrder": 0,
    "seo": {},
    "salesTitle": "string",
    "uuid": "string",
    "subscriptionPlanId": 0,
    "slug": "string",
    "image": "string",
    "name": "string",
    "description": {},
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "status": "draft",
    "isAvailableOnMyPage": true,
    "isAvailableViaSlug": true,
    "isAvailableForManualOrderViaAdmin": true,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "tenantId": 0,
    "onboardingWelcomeRedirectCTAText": {},
    "customPeriodText": {},
    "orderCtaLabel": {},
    "introPeriodFixedEndDate": "2019-08-24T14:15:22Z",
    "packageProducts": [],
    "subscriptionPlan": {
      "paymentProviders": [],
      "entityTags": [],
      "subscriptionPlanProducts": [],
      "packages": [],
      "memberPackages": [],
      "metaData": {}
    },
    "payments": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "subscriptionPlan": {
    "paymentProviders": [],
    "name": "string",
    "uuid": "string",
    "billingPeriod": "monthly",
    "billingPeriodUnit": "day",
    "billingPeriodFrequency": 0,
    "autoRenew": true,
    "status": "draft",
    "tenantId": 0,
    "allowSameSubscriptionChange": true,
    "allowDifferentSubscriptionSwitch": true,
    "allowAdminSameSubscriptionChange": true,
    "allowAdminDifferentSubscriptionSwitch": true,
    "enableGiftSubscription": true,
    "allowFutureStartDate": true,
    "showAsOptionOnSubscriptionSwitch": true,
    "showAsOptionOnAdminSubscriptionSwitch": true,
    "offerSwitchOnCheckout": true,
    "tenant": {
      "additionalFeatures": [],
      "disabledFeatures": [],
      "taxRates": [],
      "products": [],
      "users": [],
      "members": [],
      "roles": [],
      "subscriptionPlans": [],
      "packages": [],
      "invoices": [],
      "orders": [],
      "paymentProviders": [],
      "newslettersProviderConfig": [],
      "paymentProviderConfigs": [],
      "oidcClients": [],
      "oauthProviders": [],
      "activityLogs": [],
      "m2m_api_clients": [],
      "customProperties": [],
      "consents": [],
      "communicationTemplates": [],
      "additionalHostnames": [],
      "exportHistory": [],
      "arReportHistory": [],
      "mypageCardsSettings": [],
      "webhooks": [],
      "customOrders": [],
      "customOrderSources": [],
      "brandKits": [],
      "communicationReceivers": [],
      "metaData": {}
    },
    "entityTags": [],
    "subscriptionPlanProducts": [],
    "packages": [],
    "memberPackages": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "member": {
    "userId": 0,
    "memberNumber": 0,
    "tenantId": 0,
    "externalId": "string",
    "fullName": "<fullName>",
    "nickName": "string",
    "avatar": "string",
    "email": "string",
    "birthDate": "<birthDate>",
    "phone": "<phone>",
    "isCompany": true,
    "companyName": "string",
    "organizationNo": "string",
    "deleteAfterExpiration": true,
    "customPropertyValues": {},
    "productRecipients": [],
    "id": "string",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "memberPackageProducts": [
    {
      "memberPackageProductEmailDomains": [],
      "memberPackageProductIps": [],
      "seats": [],
      "recipients": [],
      "metaData": {}
    }
  ],
  "orders": [
    {
      "orderItems": [],
      "metaData": {}
    }
  ],
  "memberPackageProviderPayment": {
    "memberPackageId": 0,
    "paymentInfo": {},
    "isSaved": true,
    "cardInfo": {},
    "memberPackage": {
      "memberPackageProducts": [],
      "orders": [],
      "changes": [],
      "histories": [],
      "metaData": {}
    },
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "changes": [
    {
      "metaData": {}
    }
  ],
  "histories": [
    {
      "newData": {},
      "metaData": {}
    }
  ],
  "tenantId": 0,
  "tenant": {
    "market": "NO",
    "productName": "enterprise",
    "additionalFeatures": [],
    "disabledFeatures": [],
    "name": "string",
    "isActive": true,
    "defaultLanguage": "en",
    "hostName": "string",
    "logo": "string",
    "favicon": "string",
    "authLogo": "string",
    "authLogoHeight": 0,
    "siteUrl": "string",
    "termsUrl": "string",
    "privacyUrl": "string",
    "gtm": "string",
    "taxRates": [],
    "smsOtp": true,
    "emailProvider": "brevo",
    "tenantContact": "string",
    "registeredBusinessNo": "string",
    "bankAccountNo": "string",
    "swiftCode": "string",
    "iban": "<iban>",
    "defaultLogoutURL": "string",
    "postalAddress": "<postalAddress>",
    "otpTemplateId": {},
    "smsSenderId": 0,
    "emailSenderId": 0,
    "smsSender": {
      "metaData": {}
    },
    "emailSender": {
      "metaData": {}
    },
    "products": [],
    "users": [],
    "members": [],
    "roles": [],
    "subscriptionPlans": [],
    "packages": [],
    "invoices": [],
    "orders": [],
    "paymentProviders": [],
    "newslettersProviderConfig": [],
    "paymentProviderConfigs": [],
    "oidcClients": [],
    "oauthProviders": [],
    "activityLogs": [],
    "m2m_api_clients": [],
    "customProperties": [],
    "consents": [],
    "preference": {
      "inputFieldConfig": [],
      "customFieldsOnMemberCard": [],
      "customFieldsOnInvoice": [],
      "visibleAdditionalFieldsOnMypage": [],
      "metaData": {}
    },
    "settings": {
      "aiResidency": {},
      "metaData": {}
    },
    "communicationTemplates": [],
    "additionalHostnames": [],
    "exportHistory": [],
    "arReportHistory": [],
    "mypageCardsSettings": [],
    "webhooks": [],
    "customOrders": [],
    "customOrderSources": [],
    "brandKits": [],
    "communicationReceivers": [],
    "id": 0,
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "deletedAt": "2019-08-24T14:15:22Z",
    "metaData": {}
  },
  "id": 0,
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "deletedAt": "2019-08-24T14:15:22Z",
  "metaData": {},
  "planName": "string",
  "packageName": "string",
  "email": "string",
  "fullName": "<fullName>",
  "paymentDate": "string",
  "paymentMethod": "string"
}
```

<a id="get-api-v1-product-packages-duplicated-packages-with-slug-tenantid-slug"></a>
## get duplicated packages with slug

`GET /api/v1/product-packages/duplicated-packages-with-slug/{tenantId}/{slug}`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `tenantId` (Required) | path | `number` |   |
| `slug` (Required) | path | `string` |   |
| `email` (Required) | query | `string (email)` |   |

### Responses

#### 200

Content type: `application/json` · `array of MinimalMemberPackageResponseDto`

| Name | Type | Description |
| --- | --- | --- |
| `[].packageName` (Required when parent is present) | `string` |   |
| `[].memberEmail` (Required when parent is present) | `string` |   |
| `[].status` (Required when parent is present) | `string` |   |
| `[].nextRenewal` (Required when parent is present) | `string (date-time)` |   |
| `[].expiresAt` (Required when parent is present) | `string (date-time)` |   |
| `[].currentPeriodStart` (Required when parent is present) | `string (date-time)` |   |
| `[].autoRenew` (Required when parent is present) | `boolean` |   |

#### 400

Content type: `application/json` · `ErrorResponse`

The tenantId is not an integer, the slug is malformed, the email is missing or invalid, or the campaign has ended; field codes in errors\[\]

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"badRequest"`, `"internalServerError"`, `"campaignIsOver"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

Content type: `application/json` · `ErrorResponse`

unauthorized

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 404

Content type: `application/json` · `ErrorResponse`

No published package has that slug in the tenant, or it is not offered via its slug

Same fields as [Get a package by slug (404)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages-slug-tenantid-slug).

**Example response**

`application/json`

```json
{
  "messageCode": "packageNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/duplicated-packages-with-slug/{tenantId}/{slug}?email=%3Cemail%3E' \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
[
  {
    "packageName": "string",
    "memberEmail": "string",
    "status": "string",
    "nextRenewal": "2019-08-24T14:15:22Z",
    "expiresAt": "2019-08-24T14:15:22Z",
    "currentPeriodStart": "2019-08-24T14:15:22Z",
    "autoRenew": true
  }
]
```

<a id="get-api-v1-product-packages-packages-with-subscription-plans-tenantid"></a>
## get packages with subscription plans

`GET /api/v1/product-packages/packages-with-subscription-plans/{tenantId}`

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `tenantId` (Required) | path | `number` |   |
| `email` | query | `string (email)` |   |
| `phone` | query | `string` | `maxLength`: `20` |

### Responses

#### 200

Content type: `application/json` · `array of MinimalMemberPackageResponseWithPlanDto`

| Name | Type | Description |
| --- | --- | --- |
| `[].packageName` (Required when parent is present) | `string` |   |
| `[].status` (Required when parent is present) | `string` |   |
| `[].planName` (Required when parent is present) | `string` |   |

#### 400

Content type: `application/json` · `ErrorResponse`

The tenantId is not an integer, or neither a valid email nor a phone is given; field codes in errors\[\]

Same fields as [Get all packages of the tenant (400)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

Content type: `application/json` · `ErrorResponse`

unauthorized

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 404

Content type: `application/json` · `ErrorResponse`

memberNotFound

| Name | Type | Description |
| --- | --- | --- |
| `messageCode` (Required) | `string` | Allowed values: `"memberNotFound"` |
| `message` | `string` |   |
| `errors` (Required) | `array of FieldError` |   |
| `errors[].field` (Required when parent is present) | `string` |   |
| `errors[].fieldValue` (Required when parent is present) | `string` |   |
| `errors[].identifier` (Required when parent is present) | `string` |   |
| `errors[].identifierValue` (Required when parent is present) | `string` |   |
| `errors[].messageCode` (Required when parent is present) | `string` |   |
| `errors[].message` | `string` |   |
| `errors[].errorType` (Required when parent is present) | `string` |   |

**Example response**

`application/json`

```json
{
  "messageCode": "memberNotFound",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/packages-with-subscription-plans/{tenantId}' \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
[
  {
    "packageName": "string",
    "status": "string",
    "planName": "string"
  }
]
```

<a id="get-api-v1-product-packages-repeat-purchase-eligibility-tenantid-packageid"></a>
## Check whether a member may buy the same package again, per the package repeat-purchase control

`GET /api/v1/product-packages/repeat-purchase-eligibility/{tenantId}/{packageId}`

Returns { verdict: allow \| warn \| block }. Shares the same evaluator as the payment-intent enforcement (SUBRITE-467) so checkout and the backend never drift.

**Authentication:** Bearer token (JWT)

### Parameters

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `tenantId` (Required) | path | `number` |   |
| `packageId` (Required) | path | `number` |   |
| `email` | query | `string (email)` |   |
| `phone` | query | `string` | `maxLength`: `20` |

### Responses

#### 200

Content type: `application/json` · `RepeatPurchaseEligibilityResponseDto`

| Name | Type | Description |
| --- | --- | --- |
| `verdict` (Required) | `string` | Allowed values: `"allow"`, `"warn"`, `"block"` |
| `reason` | `string` | Can be null |

#### 400

Content type: `application/json` · `ErrorResponse`

A path segment is not an integer, or the email or phone is invalid; field codes in errors\[\]

Same fields as [Get all packages of the tenant (400)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "badRequest",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 401

Content type: `application/json` · `ErrorResponse`

unauthorized

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

**Example response**

`application/json`

```json
{
  "messageCode": "string",
  "message": "string",
  "errors": [
    {}
  ]
}
```

#### 403

Content type: `application/json` · `ErrorResponse`

forbiddenResource

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

#### 500

Content type: `application/json` · `ErrorResponse`

internalServerError

Same fields as [Get all packages of the tenant (403)](https://www.subrite.no/developers/product-package?md=true#get-api-v1-product-packages).

### Example request

```bash
curl 'https://api.subrite.no/api/v1/product-packages/repeat-purchase-eligibility/{tenantId}/{packageId}' \
  --header 'Authorization: Bearer <token>'
```

### Example response

200 · `application/json`

```json
{
  "verdict": "allow",
  "reason": "string"
}
```
