---
title: "Synchronize a purchase"
description: "Verify a store purchase and attach its Feature access to a customer."
api: POST https://i.nuxie.ai/purchase
authMethod: none
playground: simple
search:
  tags: ["api", "app", "reference"]
  keywords: ["StoreKit", "Google Play Billing", "transaction_jwt", "purchase_token", "idempotent_replay"]
---

Attach a verified App Store or Google Play purchase to a customer and return the resulting Feature access. `type` selects the store; `distinct_id` identifies the customer for either store.

The iOS SDK's default StoreKit integration sends verified transactions, retries synchronization, and finishes transactions for you. For another billing provider, see [purchase ownership](/docs/ios-sdk/purchases#explicit-storekit-finishing-ownership).

## Request body

- **`apiKey`** · body · `string` · required

  Publishable key for the app platform. A `pk_test_` key selects test data; a `pk_live_` key selects live data. Copy it from **Connect your app**.

- **`type`** · body · `string` · required

  `appstore` or `playstore`.

- **`distinct_id`** · body · `string` · required

  The identified or anonymous customer ID your app supplies to the SDK, rather than Nuxie's internal customer record ID. See [Customer identifiers](/docs/api-reference/rest-api#customer-identifiers).

- **`transaction_jwt`** · body · `string`

  Required for `appstore`: the signed transaction returned by StoreKit 2.

- **`purchase_token`** · body · `string`

  Required for `playstore`: the token returned by Google Play Billing.

- **`product_id`** · body · `string`

  Google Play Product identifier, when relevant.

- **`base_plan_id`** · body · `string`

  Google Play subscription base plan, when relevant.

- **`purchase_option_id`** · body · `string`

  Google Play one-time purchase option, when relevant.

- **`offer_id`** · body · `string`

  Selected Google Play store offer, when relevant.

- **`product_type`** · body · `string`

  Google Play `subscription` or `one_time`.

Use the publishable key for the matching iOS or Android platform. The configured [Google Play connection](/docs/integrations/google-play) supplies the package context. Nuxie verifies the purchase with the store before attaching access to the customer.

## Response

- **`success`** · `boolean` · required

  `true` when the purchase is attached.

- **`customer_id`** · `string` · required

  Nuxie's resolved customer record ID.

- **`features`** · `object[]` · required

  Resulting Feature access.

- **`idempotent_replay`** · `boolean` · required

  Whether this purchase was already processed.

- **`transaction_id`** · `string`

  App Store transaction identifier, returned for `appstore`.

- **`purchase_token`** · `string`

  Google Play purchase token, returned for `playstore`.

- **`order_id`** · `string`

  Google Play order identifier, returned for `playstore`.

- **`catalog_product`** · `object`

  Google Play mapping to the matched Product, base plan, purchase option, offer, and store product type.

Repeat the same evidence when retrying. Nuxie recognizes the existing transaction or token instead of granting it twice.

## Purchase errors

Error codes use the prefix `app_store_purchase_` or `google_play_purchase_`:

| Suffix | Status | Action |
| --- | --- | --- |
| `invalid` | `400` | Check the evidence, Product identifiers, App, and environment |
| `owner_unverified` | `400` | Check the customer identity used for checkout and synchronization |
| `unsupported` | `400` | Inspect `detail` for why the purchase cannot be attached |
| `conflict` | `409` | Resolve the ownership or conflicting replay before resubmitting |
| `reconciliation_retryable` | `503` | Retry with the same evidence after a delay |
| `unavailable` | `503`, or `429` for Google Play | Retry with backoff |

```sh title="App Store"
curl https://i.nuxie.ai/purchase \
  --header 'Content-Type: application/json' \
  --data '{
  "apiKey": "pk_test_example",
  "type": "appstore",
  "distinct_id": "user-456",
  "transaction_jwt": "eyJhbGciOi..."
}'
```

```sh title="Google Play"
curl https://i.nuxie.ai/purchase \
  --header 'Content-Type: application/json' \
  --data '{
  "apiKey": "pk_test_example",
  "type": "playstore",
  "purchase_token": "token-from-google-play",
  "product_id": "premium",
  "base_plan_id": "monthly",
  "distinct_id": "user-456"
}'
```

```json title="200 · App Store"
{
  "success": true,
  "customer_id": "customer-record-id",
  "features": [],
  "transaction_id": "200000000000001",
  "idempotent_replay": false
}
```

```json title="200 · Google Play"
{
  "success": true,
  "customer_id": "customer-record-id",
  "features": [],
  "purchase_token": "token-from-google-play",
  "order_id": "google-play-order-id",
  "idempotent_replay": false,
  "catalog_product": {
    "id": "product-id",
    "store_product_id": "premium",
    "base_plan_id": "monthly",
    "purchase_option_id": null,
    "offer_id": null,
    "store_product_type": "subscription"
  }
}
```
