Migrating in-app purchase metadata to v2
Update an existing integration from the pre-4.4.1 metadata workflow to the version-based v2 workflow.
Overview
Before 4.4.1, localizations and review images attached directly to an in-app purchase, subscription, or subscription group. In 4.4.1, they attach to a version — a draft container that groups the metadata and images that go through App Review together. The pre-4.4.1 endpoints remain available for existing integrations, but new work uses the version-based path.
The version model separates a product’s stable properties (product ID, type, pricing) from its reviewable metadata (localized names, descriptions, review images). Each review cycle produces one version. When you need to change any localization or image, you create a new version rather than editing the live product.
Endpoint mapping
Each deprecated v1 endpoint has a v2 equivalent that targets a version. The v1 endpoint keeps working; use it only for existing integrations that haven’t moved yet.
In-app purchase metadata and submission:
Deprecated (v1) | Replacement (v2) |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Subscription metadata and submission:
Deprecated (v1) | Replacement (v2) |
|---|---|
|
|
|
|
|
|
Subscription group metadata and submission:
Deprecated (v1) | Replacement (v2) |
|---|---|
|
|
|
|
Nested read endpoints on the parent product are also deprecated in the same window:
GET /v2/inAppPurchases/{id}/inAppPurchaseLocalizationsand its.../relationships/...variantGET /v2/inAppPurchases/{id}/imagesand its.../relationships/...variantGET /v1/subscriptions/{id}/subscriptionLocalizations,.../images, and their relationship variantsGET /v1/subscriptionGroups/{id}/subscriptionGroupLocalizationsand its relationship variant
Read localizations and images through the version instead:
GET /v1/inAppPurchaseVersions/{id}/localizationsand.../imagesGET /v1/subscriptionVersions/{id}/localizationsand.../imagesGET /v1/subscriptionGroupVersions/{id}/localizations
Migrate an in-app purchase integration
The pre-4.4.1 flow posts a localization directly against the in-app purchase:
POST /v1/inAppPurchaseLocalizations
{
"data": {
"type": "inAppPurchaseLocalizations",
"attributes": {
"locale": "en-US",
"name": "Seattle Neighborhood Coffee Map",
"description": "Find awesome coffee shops."
},
"relationships": {
"inAppPurchaseV2": {
"data": { "type": "inAppPurchases", "id": "6446452615" }
}
}
}
}In the version-based flow, create the version first, then post the localization against it:
POST /v1/inAppPurchaseVersions
{
"data": {
"type": "inAppPurchaseVersions",
"relationships": {
"inAppPurchase": {
"data": { "type": "inAppPurchases", "id": "6446452615" }
}
}
}
}POST /v2/inAppPurchaseLocalizations
{
"data": {
"type": "inAppPurchaseLocalizations",
"attributes": {
"locale": "en-US",
"name": "Seattle Neighborhood Coffee Map",
"description": "Find awesome coffee shops."
},
"relationships": {
"version": {
"data": { "type": "inAppPurchaseVersions", "id": "${inAppPurchaseVersionId}" }
}
}
}
}The relationship key changes from inAppPurchaseV2 (targeting the parent product) to version (targeting the draft version). The same shape applies to POST /v2/inAppPurchaseImages.
Migrate a submission
The pre-4.4.1 flow submits an in-app purchase directly:
POST /v1/inAppPurchaseSubmissions
{
"data": {
"type": "inAppPurchaseSubmissions",
"relationships": {
"inAppPurchaseV2": {
"data": { "type": "inAppPurchases", "id": "6446452615" }
}
}
}
}In the version-based flow, submission is a three-step review-submissions process. Create a review submission for the app, add the version as an item, and mark the submission as submitted:
POST /v1/reviewSubmissions
{
"data": {
"type": "reviewSubmissions",
"attributes": { "platform": "IOS" },
"relationships": {
"app": { "data": { "type": "apps", "id": "6446148572" } }
}
}
}POST /v1/reviewSubmissionItems
{
"data": {
"type": "reviewSubmissionItems",
"relationships": {
"reviewSubmission": {
"data": { "type": "reviewSubmissions", "id": "${reviewSubmissionId}" }
},
"inAppPurchaseVersion": {
"data": { "type": "inAppPurchaseVersions", "id": "${inAppPurchaseVersionId}" }
}
}
}
}PATCH /v1/reviewSubmissions/{id}
{
"data": {
"type": "reviewSubmissions",
"id": "${reviewSubmissionId}",
"attributes": { "submitted": true }
}
}The subscription and subscription group submission paths follow the same three-step pattern, with subscriptionVersion or subscriptionGroupVersion as the review submission item.
Update your polling code
Before 4.4.1, integrations tracked submission status by reading the parent product’s state. Now, track the version’s state field on InAppPurchaseVersion, SubscriptionVersion, or SubscriptionGroupVersion. The transitions are PREPARE_FOR_SUBMISSION → READY_FOR_REVIEW → WAITING_FOR_REVIEW → IN_REVIEW → APPROVED or REJECTED. Poll the version with GET /v1/inAppPurchaseVersions/{id} (or the equivalent for subscriptions and groups).
What doesn’t change
These pieces of the workflow are unchanged in 4.4.1:
The in-app purchase resource:
POST /v2/inAppPurchases,GET, andPATCH.The subscription resource:
POST /v1/subscriptions,GET, andPATCH.The subscription group resource:
POST /v1/subscriptionGroups,GET, andPATCH.Pricing:
/v1/inAppPurchasePriceSchedulesand/v1/subscriptionPricePointsremain the same.App Review screenshots:
/v1/inAppPurchaseAppStoreReviewScreenshotsand/v1/subscriptionAppStoreReviewScreenshotsstill target the parent product, not the version.Promoted purchases:
/v1/promotedPurchasesis unaffected.
For the full version workflow, see Working with in-app purchase versions, Working with subscription versions, and Working with subscription group versions.