---
title: "Package"
permalink: "/docs/api-v2/package"
original_source: "openapi-spec/api-v2.yaml"
---

> **AI agents:** This is the Markdown version of a RevenueCat documentation page. For the complete documentation index, see [llms.txt](https://www.revenuecat.com/docs/llms.txt).

# Package

## Package

Operations about packages.

### Get a package

`GET /projects/{project_id}/packages/{package_id}`

Operation ID: `get-package`

This endpoint requires the following permission(s): <code>project_configuration:packages:read</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `package_id` | path | yes | ID of the package |
| `expand` | query | no | Specifies which fields in the response should be expanded. Accepted values are: `product` (requires `project_configuration:products:read` permission). |

**Responses**

- `200` — Success
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `200` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. One of: `package` |
| `id` | string | yes | The id of the package |
| `lookup_key` | string | yes | The lookup_key of the package |
| `display_name` | string | yes | The display name of the package |
| `position` | integer | yes | The position of the package within the offering |
| `created_at` | integer | yes | The date the package was created at in ms since epoch |
| `products` | object | no |  |

<details><summary><code>products</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of PackageProductAssociation | yes | Product association |
| `next_page` | string | yes | URL to access the next page of the project's products. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

<details><summary><code>items</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product` | Product | yes |  |
| `eligibility_criteria` | EligibilityCriteria | yes | One of: `all`, `google_sdk_lt_6`, `google_sdk_ge_6` |

</details>
</details>
### Update a package

`POST /projects/{project_id}/packages/{package_id}`

Operation ID: `update-package`

This endpoint requires the following permission(s): <code>project_configuration:packages:read_write</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `package_id` | path | yes | ID of the package |

**Request body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `display_name` | string | no | The display name of the package |
| `position` | integer | no | The position of the package within the offering |

**Responses**

- `200` — Success. The package was updated
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `409` — Conflict
- `422` — Unprocessable entity
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `200` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. One of: `package` |
| `id` | string | yes | The id of the package |
| `lookup_key` | string | yes | The lookup_key of the package |
| `display_name` | string | yes | The display name of the package |
| `position` | integer | yes | The position of the package within the offering |
| `created_at` | integer | yes | The date the package was created at in ms since epoch |
| `products` | object | no |  |

<details><summary><code>products</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of PackageProductAssociation | yes | Product association |
| `next_page` | string | yes | URL to access the next page of the project's products. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

<details><summary><code>items</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product` | Product | yes |  |
| `eligibility_criteria` | EligibilityCriteria | yes | One of: `all`, `google_sdk_lt_6`, `google_sdk_ge_6` |

</details>
</details>
### Delete a package

`DELETE /projects/{project_id}/packages/{package_id}`

Operation ID: `delete-package-from-offering`

This endpoint requires the following permission(s): <code>project_configuration:packages:read_write</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `package_id` | path | yes | ID of the package |

**Responses**

- `200` — Success
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `409` — Conflict
- `422` — Unprocessable entity
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `200` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | The type of the deleted object One of: `app`, `chart_annotation`, `customer`, `discount`, `entitlement`, `experiment`, `offering`, `package`, `paywall`, `product`, `virtual_currency`, `webhook_integration` |
| `id` | string | yes | The ID of the deleted object |
| `deleted_at` | integer | yes | The date when the object was deleted in ms since epoch |

### Get a list of packages in an offering

`GET /projects/{project_id}/offerings/{offering_id}/packages`

Operation ID: `list-packages`

This endpoint requires the following permission(s): <code>project_configuration:packages:read</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `offering_id` | path | yes | ID of the offering |
| `starting_after` | query | no | Pagination cursor. Pass the id of the last item from the previous page to fetch the next page; omit for the first page. |
| `limit` | query | no | Maximum number of items to return per page. Values below 1 or above 100 are clamped to that range rather than rejected. |
| `expand` | query | no | Specifies which fields in the response should be expanded. Accepted values are: `items.product` (requires `project_configuration:products:read` permission). |

**Responses**

- `200` — Success
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `200` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of Package | yes | Details about each object. |
| `next_page` | string | yes | URL to access the next page of the project's packages. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

<details><summary><code>items</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. One of: `package` |
| `id` | string | yes | The id of the package |
| `lookup_key` | string | yes | The lookup_key of the package |
| `display_name` | string | yes | The display name of the package |
| `position` | integer | yes | The position of the package within the offering |
| `created_at` | integer | yes | The date the package was created at in ms since epoch |
| `products` | object | no |  |

<details><summary><code>products</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of PackageProductAssociation | yes | Product association |
| `next_page` | string | yes | URL to access the next page of the project's products. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

</details>
</details>
### Create a package

`POST /projects/{project_id}/offerings/{offering_id}/packages`

Operation ID: `create-packages`

This endpoint requires the following permission(s): <code>project_configuration:packages:read_write</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `offering_id` | path | yes | ID of the offering |

**Request body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `lookup_key` | string | yes | The lookup_key of the package |
| `display_name` | string | yes | The display name of the package |
| `position` | integer | no | The position of the package in the offering |

**Responses**

- `201` — Success. The package was created
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `409` — Conflict
- `422` — Unprocessable entity
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `201` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. One of: `package` |
| `id` | string | yes | The id of the package |
| `lookup_key` | string | yes | The lookup_key of the package |
| `display_name` | string | yes | The display name of the package |
| `position` | integer | yes | The position of the package within the offering |
| `created_at` | integer | yes | The date the package was created at in ms since epoch |
| `products` | object | no |  |

<details><summary><code>products</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of PackageProductAssociation | yes | Product association |
| `next_page` | string | yes | URL to access the next page of the project's products. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

<details><summary><code>items</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product` | Product | yes |  |
| `eligibility_criteria` | EligibilityCriteria | yes | One of: `all`, `google_sdk_lt_6`, `google_sdk_ge_6` |

</details>
</details>
### Get a list of products attached to a given package of an offering

`GET /projects/{project_id}/packages/{package_id}/products`

Operation ID: `get-products-from-package`

This endpoint requires the following permission(s): <code>project_configuration:packages:read</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `package_id` | path | yes | ID of the package |
| `starting_after` | query | no | Pagination cursor. Pass the id of the last item from the previous page to fetch the next page; omit for the first page. |
| `limit` | query | no | Maximum number of items to return per page. Values below 1 or above 100 are clamped to that range rather than rejected. |

**Responses**

- `200` — Success
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `200` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of PackageProductAssociation | yes | Details about each object. |
| `next_page` | string | yes | URL to access the next page of the entitlement's products. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

<details><summary><code>items</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product` | Product | yes |  |
| `eligibility_criteria` | EligibilityCriteria | yes | One of: `all`, `google_sdk_lt_6`, `google_sdk_ge_6` |

<details><summary><code>product</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `state` | string | yes | Whether the product is active or inactive (archived). One of: `active`, `inactive` |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `product` |
| `id` | string | yes | The id of the product |
| `store_identifier` | string | yes | The store product identifier |
| `type` | ProductType | yes | One of: `subscription`, `one_time`, `consumable`, `non_consumable`, `non_renewing_subscription` |
| `subscription` | SubscriptionProduct | no |  |
| `one_time` | OneTimeProduct | no |  |
| `created_at` | integer | yes | The date when the product was created in ms since epoch |
| `app_id` | string | yes | The id of the app |
| `app` | App | no |  |
| `indicative_price` | IndicativePrice | no | An indicative price for a product, in the default currency/country (USD / US). Uses the same price source as the get-offering-prices endpoint. |
| `display_name` | string | yes | The display name of the product |

</details>
</details>
### Attach a set of products to a package

`POST /projects/{project_id}/packages/{package_id}/actions/attach_products`

Operation ID: `attach-products-to-package`

This endpoint requires the following permission(s): <code>project_configuration:packages:read_write</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `package_id` | path | yes | ID of the package |

**Request body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `products` | array of PackageProductIDAssociation | yes | Product association list |

<details><summary><code>products</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product_id` | string | yes |  |
| `eligibility_criteria` | EligibilityCriteria | yes | One of: `all`, `google_sdk_lt_6`, `google_sdk_ge_6` |

</details>
**Responses**

- `200` — Success. The products were attached to the package.
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `409` — Conflict
- `422` — Unprocessable entity
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `200` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. One of: `package` |
| `id` | string | yes | The id of the package |
| `lookup_key` | string | yes | The lookup_key of the package |
| `display_name` | string | yes | The display name of the package |
| `position` | integer | yes | The position of the package within the offering |
| `created_at` | integer | yes | The date the package was created at in ms since epoch |
| `products` | object | no |  |

<details><summary><code>products</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of PackageProductAssociation | yes | Product association |
| `next_page` | string | yes | URL to access the next page of the project's products. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

<details><summary><code>items</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product` | Product | yes |  |
| `eligibility_criteria` | EligibilityCriteria | yes | One of: `all`, `google_sdk_lt_6`, `google_sdk_ge_6` |

</details>
</details>
### Detach a set of products from a package

`POST /projects/{project_id}/packages/{package_id}/actions/detach_products`

Operation ID: `detach-products-from-package`

This endpoint requires the following permission(s): <code>project_configuration:packages:read_write</code>. This endpoint belongs to the <strong>Project Configuration</strong> domain, which has a default rate limit of <strong>60 requests per minute</strong>.

**Parameters**

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | path | yes | ID of the project |
| `package_id` | path | yes | ID of the package |

**Request body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product_ids` | array of string | yes | IDs of the products to detach from the package |

**Responses**

- `200` — Success
- `400` — Bad request
- `401` — Unauthorized
- `403` — Access denied
- `404` — Not found
- `409` — Conflict
- `422` — Unprocessable entity
- `423` — Locked
- `429` — The request could not be completed because the rate limiting domain for this endpoint is currently at its limit for this project.
- `500` — Internal server error
- `503` — Internal server error

**Response `200` body**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. One of: `package` |
| `id` | string | yes | The id of the package |
| `lookup_key` | string | yes | The lookup_key of the package |
| `display_name` | string | yes | The display name of the package |
| `position` | integer | yes | The position of the package within the offering |
| `created_at` | integer | yes | The date the package was created at in ms since epoch |
| `products` | object | no |  |

<details><summary><code>products</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | String representing the object's type. Objects of the same type share the same value. Always has the value `list`. One of: `list` |
| `items` | array of PackageProductAssociation | yes | Product association |
| `next_page` | string | yes | URL to access the next page of the project's products. If not present / null, there is no next page |
| `url` | string | yes | The URL where this list can be accessed. |

<details><summary><code>items</code></summary>

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product` | Product | yes |  |
| `eligibility_criteria` | EligibilityCriteria | yes | One of: `all`, `google_sdk_lt_6`, `google_sdk_ge_6` |

</details>
</details>
