---
title: "Purchase intents"
description: "Create controlled, shareable Buy links that send customers directly from a product offer to Inttegro Checkout."
canonical: "https://studio.inttegro.com/api/purchase-intents"
format: inttegro-machine-docs/v1
language: "TypeScript"
sdk_version: "v12.0.0"
reader_profile: optional
reader_manifest: "https://studio.inttegro.com/machine/typescript/readers/index.json"
reader_identification: "Optional: declare your client only if known and your current-session capabilities; use reader_manifest for supplemental recommendations."
preamble_estimated_tokens: 748
model_token_report: "https://studio.inttegro.com/machine/token-report.json"
preamble_questions: 5
preamble_source: "machine-only-decisions"
recommended_mcp_tools: ["get_buy_link","list_buy_links","create_buy_link"]
estimated_tokens: 10446
token_estimate_method: "utf8_bytes_divided_by_4"
---

## Machine preamble

**Summary:** Create controlled, shareable Buy links that send customers directly from a product offer to Inttegro Checkout. This TypeScript representation uses the selected SDK's native names wherever Studio has a verified mapping.

### Five questions

#### Q1. Is Purchase intents the right source for this task?

Use this reference for create controlled, shareable buy links that send customers directly from a product offer to inttegro checkout. For the complete outcome or lifecycle, start with [Accept payment with Inttegro Checkout](https://studio.inttegro.com/machine/typescript/guides/accept-payment-with-inttegro-checkout.md); return here for exact operations and fields.

#### Q2. What does “A purchase intent is offer configuration, not a reserved or completed order” require?

**A purchase intent is offer configuration, not a reserved or completed
order.** Creation returns a shareable Buy-link identifier; an order appears
only after a customer checks out. Use the resulting order's [`order.createdFrom`](https://typescript.inttegro.dev/v12.0.0)attribution when tracing the conversion.

#### Q3. What does “Verify catalog eligibility at the time of use” require?

**Verify catalog eligibility at the time of use.** A referenced price must
belong to the selected product and be active and unarchived. A comparison
price is display context and does not determine the charged amount.

#### Q4. What does “Treat omitted quantity fields deliberately during update” require?

**Treat omitted quantity fields deliberately during update.** Omitting the
entire quantity object preserves both bounds; sending the object without its
optional maximum removes an existing upper limit.

#### Q5. What does “Choose exactly one usage policy” require?

**Choose exactly one usage policy.** Omit usage or select multi-use for a
reusable link; select single-use for one resulting order. Never send both
flags. Read [Purchase intents](https://studio.inttegro.com/machine/typescript/products/purchase-intents.md) before designing a
more complex offer lifecycle.

### Recommended MCP assistance

Use these through an authenticated Inttegro MCP connection. This document remains the contract source.

- [`get_buy_link`](https://studio.inttegro.com/machine/typescript/inttegro-mcp/tools.md#get_buy_link) — read; no mutation confirmation. Gets one buy link and its current lifecycle status by purchase-intent ID.
- [`list_buy_links`](https://studio.inttegro.com/machine/typescript/inttegro-mcp/tools.md#list_buy_links) — read; no mutation confirmation. Lists a bounded page of product buy links with status, quantity rules, and public URLs.
- [`create_buy_link`](https://studio.inttegro.com/machine/typescript/inttegro-mcp/tools.md#create_buy_link) — action; exact user confirmation required. Creates a public hosted buy link for one existing product and price with a minimum quantity, optional maximum quantity and expiry, and single- or multi-use behavior.

## Document content

# Purchase intents

Purchase intents power Buy links: share a product offer and let Inttegro handle the customer-facing checkout. Use this API to create the link, change its quantity or availability, and stop it.

The API returns a `sale_...` ID. Append it to `https://pages.inttegro.com/buy/` to create the customer-facing URL. For the complete sales flow, see the [Purchase intents product guide](https://studio.inttegro.com/machine/typescript/products/purchase-intents.md).

## Distinguish an offer link from the order it may create

The four decision rules are in the machine preamble above.

## The purchase intent object

A purchase intent contains the offer shown at checkout: its product, price, quantity limits, availability, and usage policy. Its status changes automatically when the link expires, is canceled, or uses its single allowed purchase.

### Properties

- [`allowVariants`](https://typescript.inttegro.dev/v12.0.0) — `boolean` — required

  Whether the offer uses a variant set. When
  [`purchaseIntent.variantSet`](https://typescript.inttegro.dev/v12.0.0) is present, checkout can
  offer its active, available variants.

- [`createdAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp` — required

  When the purchase intent was created.

- [`expiresAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp|null`

  Optional timestamp after which the Buy link stops accepting new purchases.
  Expiry is effective at the timestamp itself.

- [`id`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

  Unique purchase intent identifier with the `sale_` prefix.

- [`inactiveAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp|null`

  When the merchant explicitly inactivated the Buy link. When this is set, the
  intent is unavailable even if [`purchaseIntent.expiresAt`](https://typescript.inttegro.dev/v12.0.0)
  is still in the future.

- [`merchant`](https://typescript.inttegro.dev/v12.0.0)

  Business identity shown in the hosted checkout. Individual fields are omitted when unavailable.

  - [`merchant.appName`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Human-readable application name.

  - [`merchant.organizationId`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Organization that owns the application.

  - [`merchant.organizationName`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Human-readable organization name.

- [`price`](https://typescript.inttegro.dev/v12.0.0)

  Resolved price used for the offer. Amounts use integer minor units.

  - [`price.active`](https://typescript.inttegro.dev/v12.0.0) — `boolean` — required

    Whether the resolved price can be used.

  - [`price.id`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Catalog price identifier when the offer uses a stored price.

  - [`price.label`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Catalog price label when available.

  - [`price.nominal`](https://typescript.inttegro.dev/v12.0.0) — `object` — required

    Amount the customer pays.

    - [`price.nominal.currency`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Lowercase currency code.

    - [`price.nominal.value`](https://typescript.inttegro.dev/v12.0.0) — `integer` — required

      Amount in the currency's smallest unit.

  - [`price.original`](https://typescript.inttegro.dev/v12.0.0) — `object`

    Optional comparison price shown alongside the amount charged.

    - [`price.original.active`](https://typescript.inttegro.dev/v12.0.0) — `boolean` — required

      Whether the resolved comparison price is active.

    - [`price.original.id`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Catalog price identifier when the comparison price is stored.

    - [`price.original.label`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Comparison-price label when available.

    - [`price.original.nominal`](https://typescript.inttegro.dev/v12.0.0) — `object` — required

      Comparison amount.

      - [`price.original.nominal.currency`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

        Lowercase currency code.

      - [`price.original.nominal.value`](https://typescript.inttegro.dev/v12.0.0) — `integer` — required

        Amount in the currency's smallest unit.

- [`presentation`](https://typescript.inttegro.dev/v12.0.0)

  Merchant-authored Buy-page copy. Omitted fields continue to use product-aware defaults.

  - [`presentation.buyPage`](https://typescript.inttegro.dev/v12.0.0) — `object`

    Presentation overrides for the hosted Buy page.

    - [`presentation.buyPage.text`](https://typescript.inttegro.dev/v12.0.0) — `object`

      Plain-text labels that differ from the defaults.

      - [`presentation.buyPage.text.amountFieldLabel`](https://typescript.inttegro.dev/v12.0.0) — `string`

        Label above a customer-selected amount input.

      - [`presentation.buyPage.text.checkoutSectionTitle`](https://typescript.inttegro.dev/v12.0.0) — `string`

        Heading above the Buy-page form.

      - [`presentation.buyPage.text.primaryActionLabel`](https://typescript.inttegro.dev/v12.0.0) — `string`

        Ready-state primary action label.

- [`product`](https://typescript.inttegro.dev/v12.0.0)

  Current catalog product rendered by the hosted checkout.

  - [`product.about`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Full product description.

  - [`product.active`](https://typescript.inttegro.dev/v12.0.0) — `boolean` — required

    Whether the product is published and available.

  - [`product.archivedAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp|null`

    When the product was archived.

  - [`product.attributes`](https://typescript.inttegro.dev/v12.0.0) — `array`

    Product attributes.

    - [`product.attributes.name`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Attribute name.

    - [`product.attributes.value`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Attribute value.

  - [`product.category`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Product category.

  - [`product.createdAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp` — required

    When the product was created.

  - [`product.customData`](https://typescript.inttegro.dev/v12.0.0) — `object|null`

    Product metadata, returned as string values.

  - [`product.description`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Short product description.

  - [`product.dimensions`](https://typescript.inttegro.dev/v12.0.0) — `object|null`

    Physical, digital, or custom size information.

    - [`product.dimensions.custom`](https://typescript.inttegro.dev/v12.0.0) — `object`

      Custom dimension details.

      - [`product.dimensions.custom.details`](https://typescript.inttegro.dev/v12.0.0) — `object`

        Custom dimension values.

      - [`product.dimensions.custom.size`](https://typescript.inttegro.dev/v12.0.0) — `number`

        Custom size.

      - [`product.dimensions.custom.sizeUnit`](https://typescript.inttegro.dev/v12.0.0) — `string`

        Unit used for custom size.

    - [`product.dimensions.digital`](https://typescript.inttegro.dev/v12.0.0) — `object`

      Digital file size.

      - [`product.dimensions.digital.bytes`](https://typescript.inttegro.dev/v12.0.0) — `number`

        File size in bytes.

      - [`product.dimensions.digital.size`](https://typescript.inttegro.dev/v12.0.0) — `number`

        File size expressed in the accompanying unit.

      - [`product.dimensions.digital.sizeUnit`](https://typescript.inttegro.dev/v12.0.0) — `string`

        Unit used for digital size.

    - [`product.dimensions.physical`](https://typescript.inttegro.dev/v12.0.0) — `object`

      Physical measurements.

      - [`product.dimensions.physical.height`](https://typescript.inttegro.dev/v12.0.0) — `number`

        Product height.

      - [`product.dimensions.physical.length`](https://typescript.inttegro.dev/v12.0.0) — `number`

        Product length.

      - [`product.dimensions.physical.volume`](https://typescript.inttegro.dev/v12.0.0) — `number`

        Product volume.

      - [`product.dimensions.physical.volumeUnit`](https://typescript.inttegro.dev/v12.0.0) — `string`

        Unit used for volume.

      - [`product.dimensions.physical.weight`](https://typescript.inttegro.dev/v12.0.0) — `number`

        Product weight.

      - [`product.dimensions.physical.weightUnit`](https://typescript.inttegro.dev/v12.0.0) — `string`

        Unit used for weight.

      - [`product.dimensions.physical.width`](https://typescript.inttegro.dev/v12.0.0) — `number`

        Product width.

  - [`product.id`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

    Unique product identifier with the prod\_ prefix.

  - [`product.media`](https://typescript.inttegro.dev/v12.0.0) — `object|null`

    Product media shown during browsing and checkout.

    - [`product.media.brandLogo`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Brand logo reference or URL.

    - [`product.media.demoVideo`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Demo video reference or URL.

    - [`product.media.downloads`](https://typescript.inttegro.dev/v12.0.0) — `array`

      Downloadable asset references or URLs.

    - [`product.media.gallery`](https://typescript.inttegro.dev/v12.0.0) — `array`

      Additional image references or URLs.

    - [`product.media.heroImage`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Primary image reference or URL.

    - [`product.media.infographic`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Infographic reference or URL.

    - [`product.media.promoVideo`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Promotional video reference or URL.

    - [`product.media.thumbnail`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Thumbnail reference or URL.

    - [`product.media.webPageUrl`](https://typescript.inttegro.dev/v12.0.0) — `string`

      Product web page URL.

  - [`product.name`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

    Product name.

  - [`product.prices`](https://typescript.inttegro.dev/v12.0.0) — `array`

    Non-archived catalog prices currently attached to the product.

    - [`product.prices.active`](https://typescript.inttegro.dev/v12.0.0) — `boolean` — required

      Whether the catalog price is active.

    - [`product.prices.id`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Catalog price identifier.

    - [`product.prices.label`](https://typescript.inttegro.dev/v12.0.0) — `string|null`

      Short price label.

    - [`product.prices.nominal`](https://typescript.inttegro.dev/v12.0.0) — `object` — required

      Catalog price amount.

      - [`product.prices.nominal.currency`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

        Lowercase currency code.

      - [`product.prices.nominal.value`](https://typescript.inttegro.dev/v12.0.0) — `integer` — required

        Amount in the currency's smallest unit.

  - [`product.publishedAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp|null`

    When the product was published.

  - [`product.reference`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Your product reference or SKU.

  - [`product.shipment`](https://typescript.inttegro.dev/v12.0.0) — `object|null`

    Fulfillment details copied from the product when present.

  - [`product.taxCode`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Tax classification code.

  - [`product.type`](https://typescript.inttegro.dev/v12.0.0) — `enum` — required

    Product type: [`Inttegro.ProductTypes.Cause`](https://typescript.inttegro.dev/v12.0.0/variables/types_products.ProductTypes.html#cause) , [`Inttegro.ProductTypes.Custom`](https://typescript.inttegro.dev/v12.0.0/variables/types_products.ProductTypes.html#custom) , [`Inttegro.ProductTypes.Digital`](https://typescript.inttegro.dev/v12.0.0/variables/types_products.ProductTypes.html#digital) , [`Inttegro.ProductTypes.Physical`](https://typescript.inttegro.dev/v12.0.0/variables/types_products.ProductTypes.html#physical) , [`Inttegro.ProductTypes.Service`](https://typescript.inttegro.dev/v12.0.0/variables/types_products.ProductTypes.html#service) , or [`Inttegro.ProductTypes.Voucher`](https://typescript.inttegro.dev/v12.0.0/variables/types_products.ProductTypes.html#voucher) .

  - [`product.unitDim`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Unit dimension label.

  - [`product.updatedAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp|null`

    When the product was last updated.

  - [`product.variantSetId`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Variant set configured for this Buy link.

- [`quantity`](https://typescript.inttegro.dev/v12.0.0) — required

  Quantity bounds enforced by the hosted checkout. When purchase\_intent.quantity.max is omitted, the offer has no upper quantity limit.

  - [`quantity.max`](https://typescript.inttegro.dev/v12.0.0) — `integer`

    Optional highest quantity a shopper may buy.

  - [`quantity.min`](https://typescript.inttegro.dev/v12.0.0) — `integer` — required

    Lowest quantity a shopper may buy.

- [`status`](https://typescript.inttegro.dev/v12.0.0) — `enum` — required

  Current effective state of the Buy link: [`Inttegro.PurchaseIntentStatuses.Active`](https://typescript.inttegro.dev/v12.0.0/variables/types_purchase-intents.PurchaseIntentStatuses.html#active), [`Inttegro.PurchaseIntentStatuses.Expired`](https://typescript.inttegro.dev/v12.0.0/variables/types_purchase-intents.PurchaseIntentStatuses.html#expired), [`Inttegro.PurchaseIntentStatuses.Inactive`](https://typescript.inttegro.dev/v12.0.0/variables/types_purchase-intents.PurchaseIntentStatuses.html#inactive), or[`Inttegro.PurchaseIntentStatuses.Used`](https://typescript.inttegro.dev/v12.0.0/variables/types_purchase-intents.PurchaseIntentStatuses.html#used).

- [`updatedAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp|null`

  When the merchant last changed the purchase intent.

- [`usage`](https://typescript.inttegro.dev/v12.0.0) — required

  How often the Buy link may be used.

  - [`usage.multiUse`](https://typescript.inttegro.dev/v12.0.0) — `boolean`

    When `true`, the same intent may produce multiple orders over time.

  - [`usage.order`](https://typescript.inttegro.dev/v12.0.0) — `object`

    Present after a single-use Buy link has already been consumed. Includes the resulting order ID and its creation time.

    - [`usage.order.createdAt`](https://typescript.inttegro.dev/v12.0.0) — `timestamp` — required

      When order creation consumed the Buy link.

    - [`usage.order.id`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Order that consumed the Buy link.

  - [`usage.singleUse`](https://typescript.inttegro.dev/v12.0.0) — `boolean`

    When `true`, creating the first order consumes the Buy link.

- [`variantSet`](https://typescript.inttegro.dev/v12.0.0) — `object|null`

  Active variant choices available to the customer. This can be omitted even when purchase\_intent.allow\_variants is true.

  - [`variantSet.active`](https://typescript.inttegro.dev/v12.0.0) — `boolean` — required

    Whether the variant set is active.

  - [`variantSet.defaultProductId`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Default product in the variant set.

  - [`variantSet.description`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Variant-set description.

  - [`variantSet.id`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

    Variant-set identifier.

  - [`variantSet.name`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

    Variant-set name.

  - [`variantSet.reference`](https://typescript.inttegro.dev/v12.0.0) — `string`

    Your reference for the variant set.

  - [`variantSet.variantAxes`](https://typescript.inttegro.dev/v12.0.0) — `array` — required

    Dimensions shoppers use to choose a variant.

    - [`variantSet.variantAxes.key`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Stable axis key.

    - [`variantSet.variantAxes.label`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Customer-facing axis label.

    - [`variantSet.variantAxes.position`](https://typescript.inttegro.dev/v12.0.0) — `integer` — required

      Display order of the axis.

  - [`variantSet.variants`](https://typescript.inttegro.dev/v12.0.0) — `array` — required

    Products currently available as choices in the variant set.

    - [`variantSet.variants.active`](https://typescript.inttegro.dev/v12.0.0) — `boolean` — required

      Whether this variant is active.

    - [`variantSet.variants.position`](https://typescript.inttegro.dev/v12.0.0) — `integer`

      Display order of the variant.

    - [`variantSet.variants.price`](https://typescript.inttegro.dev/v12.0.0) — `object`

      Resolved price for this variant, using the same shape as the top-level [`purchaseIntent.price`](https://typescript.inttegro.dev/v12.0.0) property.

    - [`variantSet.variants.product`](https://typescript.inttegro.dev/v12.0.0) — `object`

      Hydrated catalog product for this variant, using the same shape as the top-level [`purchaseIntent.product`](https://typescript.inttegro.dev/v12.0.0) property.

    - [`variantSet.variants.productId`](https://typescript.inttegro.dev/v12.0.0) — `string` — required

      Product represented by this variant.

    - [`variantSet.variants.variantValues`](https://typescript.inttegro.dev/v12.0.0) — `object` — required

      Axis keys and the values selected by this variant.

## Create a purchase intent

Create a hosted Buy link for a catalog product. The response includes the `sale_...` ID used in the shareable checkout URL. No order exists yet; an order is created only when a customer checks out from the link.

> **Note:**
>
> Cause products default to “Support this cause,” “Contribution amount,” and “Continue to contribute.” Other product types default to “Prepare order,” “Amount,” and “Continue to payment.” The amount label appears only when the customer can select an amount.

> Mcp Endpoint Tools is interactive content. Use the canonical page to view it.

### Rules

- Send exactly one of `product` or `productId`.
- Send exactly one of `price` or `priceId`.
- A referenced product and each referenced price must come from your catalog. The selected catalog price must be active, not archived, and belong to the selected product. An optional comparison price must belong to the selected product but does not determine what the customer is charged.
- An inline `price.nominal.value` must be at least `1` and uses the smallest currency unit. Its currency is normalized to lowercase.
- Within `price`, send exactly one of `price.id` or `price.nominal`. For comparison pricing, send at most one of `price.original` or `price.originalId`; within `price.original`, send exactly one of `price.original.id` or `price.original.nominal`.
- `quantity.min` is required and must be at least `1`.
- `quantity.max` is optional. When present, it must be at least `1` and greater than or equal to `quantity.min`; when omitted, the offer has no upper quantity limit.
- `expiresAt` must be a future RFC3339 timestamp when provided.
- `presentation.buy_page.text` is optional. Each supplied label is trimmed, must contain non-whitespace text on one line, and must fit its documented length limit. Omit the complete `presentation` object to use product-aware defaults.
- `presentation.buy_page.text.primary_action_label` controls only the ready action. Validation and loading labels remain system-owned so the button continues to describe its current state accurately.
- A `product.variantSetId` is saved as offer configuration. Variant options are returned only when that set and its eligible products are available at lookup time.
- Omit `usage` or set `usage.multiUse` to `true` for a reusable link. Set `usage.singleUse` to `true` for a link that can create only one order. Do not send both fields.

### Request attributes

- `expiresAt` — `Time`

  Optional expiry time for the Buy link. After this moment, new shoppers can no longer create orders from the intent.

- `presentation` — wire-only

  Optional plain-text overrides for the hosted Buy page. Omit this object to use product-aware defaults.

  - `presentation.buy_page` — `object` — required — wire-only

    Hosted Buy-page presentation.

    - `presentation.buy_page.text` — `object` — required — wire-only

      At least one text override is required.

      - `presentation.buy_page.text.amount_field_label` — `string` — wire-only

        Single-line label above the customer-selected amount input. Maximum 64 characters.

      - `presentation.buy_page.text.checkout_section_title` — `string` — wire-only

        Single-line heading above the Buy-page form. Maximum 80 characters.

      - `presentation.buy_page.text.primary_action_label` — `string` — wire-only

        Single-line ready-state button label. Maximum 48 characters.

- `price` — `PriceSelector`

  Price configuration for the Buy link. Use this instead of price\_id to supply an inline amount, a catalog price with comparison pricing, or both the sale and comparison amounts inline.

  - `price.id` — `string`

    Existing price identifier to reuse.

  - `price.nominal` — `InlineParams`

    Inline amount when you are not reusing a stored price ID.

    - `price.nominal.currency` — `Currency`

      Non-empty currency code, normalized to lowercase.

    - `price.nominal.value` — `number`

      Amount in the smallest currency unit.

  - `price.original` — `OriginalPriceParams`

    Optional original price for strike-through pricing when you are supplying a custom nominal amount.

    - `price.original.id` — `string`

      Stored original price identifier.

    - `price.original.nominal` — `InlineParams`

      Inline original amount when you are not reusing a stored price ID.

      - `price.original.nominal.currency` — `Currency`

        Non-empty currency code, normalized to lowercase.

      - `price.original.nominal.value` — `number`

        Amount in the smallest currency unit.

  - `price.originalId` — `string`

    Stored original price identifier when you want strike-through pricing without embedding `price.original`.

- `priceId` — `string`

  Stored catalog price to reuse for the Buy link.

- `product` — `ProductSelector`

  Product selection for the Buy link. Use this instead of product\_id when the offer should expose a variant set.

  - `product.id` — `string`

    Stored product identifier to sell through the Buy link.

  - `product.variantSetId` — `string`

    Variant set identifier when the offer should allow shoppers to switch between related products.

- `productId` — `string`

  Stored catalog product to reuse for the Buy link.

- `quantity` — `Quantity` — required

  Quantity bounds the hosted checkout enforces.

  - `quantity.min` — `number` — required

    Minimum quantity a shopper must buy.

  - `quantity.max` — `number`

    Optional maximum quantity a shopper may buy. Omit it for no upper limit.

- `usage` — `Usage`

  Optional usage policy. Omit it to create a reusable Buy link.

  - `usage.multiUse` — `boolean`

    Allow the same intent to produce multiple orders.

  - `usage.singleUse` — `boolean`

    Consume the intent when the first order is created.

**Request — POST /purchase\_intents/create**

```typescript
import * as Inttegro from '@inttegro/inttegro-sdk'

const inttegro = new Inttegro.InttegroClient({
  apiKey: process.env.INTTEGRO_API_KEY!,
})
const result = await inttegro.purchaseIntents.create({
  productId: "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
  priceId: "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
  presentation: {
    buyPage: {
      text: {
        checkoutSectionTitle: "Order your matcha",
        primaryActionLabel: "Continue with this order",
      },
    },
  },
  quantity: {
    max: 5,
    min: 1,
  },
  usage: {
    multiUse: true,
  },
  expiresAt: new Date("2030-12-01T09:00:00Z"),
})
```

```json
{
  "purchase_intent": {
    "id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
    "quantity": {
      "min": 1,
      "max": 5
    },
    "allow_variants": false,
    "usage": {
      "multi_use": true
    },
    "expires_at": "2030-12-01T09:00:00Z",
    "status": "active",
    "created_at": "2026-08-05T12:00:00Z",
    "product": {
      "id": "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
      "active": true,
      "created_at": "2026-07-28T10:00:00Z",
      "name": "Premium Matcha Tin",
      "type": "physical"
    },
    "price": {
      "id": "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
      "active": true,
      "nominal": {
        "currency": "ghs",
        "value": 18500
      }
    },
    "presentation": {
      "buy_page": {
        "text": {
          "checkout_section_title": "Order your matcha",
          "primary_action_label": "Continue with this order"
        }
      }
    }
  }
}
```

## Update a purchase intent

Change the quantity, availability window, or customer-facing labels of an existing Buy link without changing what the link sells. Product, price, variant selection, and usage mode stay fixed so a URL already shared with customers does not silently become a different offer.

> Mcp Endpoint Tools is interactive content. Use the canonical page to view it.

### Rules

- Send exactly one identifier. Use `id` for new integrations; `purchase_intent_id` remains available as a compatibility alias.
- Setting `expiresAt` to `null` clears the expiry time.
- A non-null `expiresAt` must be an RFC3339 timestamp. A past timestamp is accepted and makes the offer immediately expired.
- Setting `reactivate` to `true` clears cancellation state and any existing elapsed expiry. If the same request sets a new elapsed `expiresAt`, the intent remains expired.
- `presentation.buy_page.text` is a sparse update. Omit a label to preserve its current override; send the label as `null` to remove that override and restore the product-aware default.
- Every non-null text value is trimmed, must contain non-whitespace text on one line, and must fit its documented length limit. Appearance, validation messages, and loading labels are not configurable here.
- When supplied, `quantity` must include `quantity.min`, which must be at least `1`. Its optional `quantity.max` must be greater than or equal to `quantity.min`.
- Omitting `quantity.max` removes an existing upper quantity limit. Omit the entire `quantity` object to leave both bounds unchanged.

* Sending only the identifier is a valid no-op and returns the current object.
* A used single-use intent stays used; reactivation does not remove its order claim.

### Request attributes

- `expiresAt` — `any`

  New expiry time for the Buy link, or `null` to remove the current expiry.

- `id` — `string`

  Canonical purchase intent identifier. Required unless you use the compatibility alias.

- `presentation` — wire-only

  Sparse plain-text update for the hosted Buy page. Omitted labels are preserved; explicit null restores a product-aware default.

  - `presentation.buy_page` — `object` — required — wire-only

    Hosted Buy-page presentation update.

    - `presentation.buy_page.text` — `object` — required — wire-only

      At least one text field is required.

      - `presentation.buy_page.text.amount_field_label` — `string|null` — wire-only

        New amount-field label, up to 64 characters, or null to restore the default.

      - `presentation.buy_page.text.checkout_section_title` — `string|null` — wire-only

        New checkout-section title, up to 80 characters, or null to restore the default.

      - `presentation.buy_page.text.primary_action_label` — `string|null` — wire-only

        New ready-state action label, up to 48 characters, or null to restore the default.

- `quantity` — `Quantity`

  Replacement quantity bounds. Omit this object to leave the current bounds unchanged.

  - `quantity.min` — `number` — required

    New minimum quantity shoppers must buy.

  - `quantity.max` — `number`

    Optional new maximum. Omit it to remove the upper limit.

- `purchase_intent_id` — `string` — wire-only

  Compatibility alias for `id`. Omit this in new integrations, and never send both identifier fields.

- `reactivate` — `boolean`

  Clear state that currently prevents new purchases.

This example replaces the section title, restores the product-aware primary action with an explicit `null`, and leaves the omitted amount-field label unchanged.

**Request — POST /purchase\_intents/update**

```typescript
import * as Inttegro from '@inttegro/inttegro-sdk'

const inttegro = new Inttegro.InttegroClient({
  apiKey: process.env.INTTEGRO_API_KEY!,
})
const result = await inttegro.purchaseIntents.update({
  id: "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
  presentation: {
    buyPage: {
      text: {
        checkoutSectionTitle: "Complete your matcha order",
        primaryActionLabel: null,
      },
    },
  },
})
```

```json
{
  "purchase_intent": {
    "id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
    "quantity": {
      "min": 1,
      "max": 5
    },
    "allow_variants": false,
    "usage": {
      "multi_use": true
    },
    "expires_at": "2030-12-01T09:00:00Z",
    "status": "active",
    "created_at": "2026-08-05T12:00:00Z",
    "updated_at": "2026-08-05T12:18:00Z",
    "product": {
      "id": "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
      "active": true,
      "created_at": "2026-07-28T10:00:00Z",
      "name": "Premium Matcha Tin",
      "type": "physical"
    },
    "price": {
      "id": "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
      "active": true,
      "nominal": {
        "currency": "ghs",
        "value": 18500
      }
    },
    "presentation": {
      "buy_page": {
        "text": {
          "checkout_section_title": "Complete your matcha order"
        }
      }
    }
  }
}
```

## Cancel a purchase intent

Stop a Buy link from creating new orders immediately. Unlike expiry, cancellation happens when you choose to stop the offer. The intent remains available through the API with [`purchaseIntent.status`](https://typescript.inttegro.dev/v12.0.0) set to [`Inttegro.PurchaseIntentStatuses.Inactive`](https://typescript.inttegro.dev/v12.0.0/variables/types_purchase-intents.PurchaseIntentStatuses.html#inactive).

Canceling an already inactive intent returns its current state. A single-use intent that already created an order cannot be canceled.

Send exactly one identifier. Use `id` for new integrations; `purchase_intent_id` remains available as a compatibility alias.

> Mcp Endpoint Tools is interactive content. Use the canonical page to view it.

### Request attributes

- `id` — `string` — wire-only

  Canonical purchase intent identifier. Required unless you use the compatibility alias.

- `purchase_intent_id` — `string` — wire-only

  Compatibility alias for `id`. Omit this in new integrations, and never send both identifier fields.

**Request — POST /purchase\_intents/cancel**

```typescript
import * as Inttegro from '@inttegro/inttegro-sdk'

const inttegro = new Inttegro.InttegroClient({
  apiKey: process.env.INTTEGRO_API_KEY!,
})
const result = await inttegro.purchaseIntents.cancel({
  id: "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
})
```

```json
{
  "purchase_intent": {
    "id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
    "quantity": {
      "min": 2,
      "max": 8
    },
    "allow_variants": false,
    "usage": {
      "multi_use": true
    },
    "expires_at": "2030-12-01T09:00:00Z",
    "inactive_at": "2026-08-05T12:26:00Z",
    "status": "inactive",
    "created_at": "2026-08-05T12:00:00Z",
    "updated_at": "2026-08-05T12:26:00Z",
    "product": {
      "id": "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
      "active": true,
      "created_at": "2026-07-28T10:00:00Z",
      "name": "Premium Matcha Tin",
      "type": "physical"
    },
    "price": {
      "id": "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
      "active": true,
      "nominal": {
        "currency": "ghs",
        "value": 18500
      }
    }
  }
}
```

## Lookup a purchase intent

Retrieve the offer behind a Buy link. Public checkout can look up a `sale_...` ID without an API key, so the ID is designed to be shared with customers and is not an account credential.

Public lookup returns active and expired offers so checkout can show either the offer or an expiry message. Canceled and already-used single-use offers are not exposed publicly. Authenticate a server-side lookup when you need every lifecycle state.

> Mcp Endpoint Tools is interactive content. Use the canonical page to view it.

### Required attributes

- `id` — `string` — required — wire-only

  Purchase intent identifier with the `sale_` prefix.

**Request — POST /purchase\_intents/lookup**

```typescript
import * as Inttegro from '@inttegro/inttegro-sdk'

const inttegro = new Inttegro.InttegroClient({
  apiKey: process.env.INTTEGRO_API_KEY!,
})
const result = await inttegro.purchaseIntents.lookup({
  id: "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
})
```

```json
{
  "purchase_intent": {
    "id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
    "merchant": {
      "app_name": "Tea House",
      "organization_id": "org_3Qn7Lp5cY2vR8tMd1Ks4BxWa",
      "organization_name": "Tea House Ltd"
    },
    "quantity": {
      "min": 1,
      "max": 5
    },
    "allow_variants": true,
    "usage": {
      "multi_use": true
    },
    "status": "active",
    "created_at": "2026-08-05T12:00:00Z",
    "product": {
      "id": "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
      "variant_set_id": "pg_1Ms9Qv4rLc7tY2pNd6Bx8HwK",
      "active": true,
      "created_at": "2026-07-28T10:00:00Z",
      "name": "Premium Matcha Tin",
      "type": "physical"
    },
    "price": {
      "id": "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
      "active": true,
      "nominal": {
        "currency": "ghs",
        "value": 18500
      }
    }
  }
}
```

## List purchase intents

Browse your Buy links, newest first. Each item contains the same merchant-facing details as an authenticated lookup.

Pagination is numbered rather than cursor-based. [`page.size`](https://typescript.inttegro.dev/v12.0.0) in the response is the number of intents actually returned, which can be smaller than the requested `pageSize`. The response does not include a total count or next-page token.

> Mcp Endpoint Tools is interactive content. Use the canonical page to view it.

### Required attributes

- `pageNumber` — `number` — required

  1-based page number to fetch. Must be between 1 and 10 inclusive.

- `pageSize` — `number` — required

  Number of items to return. Must be between 1 and 256 inclusive.

**Request — POST /purchase\_intents/page**

```typescript
import * as Inttegro from '@inttegro/inttegro-sdk'

const inttegro = new Inttegro.InttegroClient({
  apiKey: process.env.INTTEGRO_API_KEY!,
})
const result = await inttegro.purchaseIntents.page({
  pageNumber: 1,
  pageSize: 20,
})
```

```json
{
  "page": {
    "number": 1,
    "size": 2,
    "purchase_intents": [
      {
        "id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
        "quantity": {
          "min": 1,
          "max": 5
        },
        "allow_variants": false,
        "usage": {
          "multi_use": true
        },
        "status": "active",
        "created_at": "2026-08-05T12:00:00Z",
        "product": {
          "id": "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
          "active": true,
          "created_at": "2026-07-28T10:00:00Z",
          "name": "Premium Matcha Tin",
          "type": "physical"
        },
        "price": {
          "id": "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
          "active": true,
          "nominal": {
            "currency": "ghs",
            "value": 18500
          }
        }
      },
      {
        "id": "sale_M4nQ7xVc2pLs8YtR1kDb5HwA",
        "quantity": {
          "min": 1,
          "max": 1
        },
        "allow_variants": false,
        "usage": {
          "single_use": true,
          "order": {
            "id": "or_9tW2xBc5pLm8Qn1Rr4Ks7YdV",
            "created_at": "2026-08-05T12:42:00Z"
          }
        },
        "status": "used",
        "created_at": "2026-08-04T17:20:00Z",
        "product": {
          "id": "prod_H2mR8vQ4kL7xT1nPs5Bc9DyW",
          "active": true,
          "created_at": "2026-07-20T09:30:00Z",
          "name": "Ceremonial Matcha Set",
          "type": "physical"
        },
        "price": {
          "id": "pr_D5xK1mQ8vR3tN7pLs2Bc9HyW",
          "active": true,
          "nominal": {
            "currency": "ghs",
            "value": 42000
          }
        }
      }
    ]
  }
}
```

## Related resources

- [Create a product](https://studio.inttegro.com/machine/typescript/api/products.md#create-a-product) - Build the catalog item a Buy link points at.
- [Create a price](https://studio.inttegro.com/machine/typescript/api/prices.md#create-a-price) - Store the catalog price a Buy link should reuse.
- [Accept payment with Inttegro Checkout](https://studio.inttegro.com/machine/typescript/guides/accept-payment-with-inttegro-checkout.md) - Put the hosted checkout experience in front of customers.
- [Create an order](https://studio.inttegro.com/machine/typescript/api/orders.md#create-an-order) - Compare direct order creation with Buy-link-driven order creation.
