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, stop it, and see how customers have used 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.
Operations
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
activityobject|nullRecent checkout activity. Public link lookups omit this object.Click or tap to expandView recent attributesClick or tap to expand
Recent activity events for this Buy link.View attribution attributesClick or tap to expand
Campaign and referral context captured for the visit.View visitor attributesClick or tap to expand
Available browser, device, location, and session context for the visitor.
productobjectCurrent catalog product rendered by the hosted checkout.Click or tap to expandView custom_data detailsClick or tap to expand
Product metadata, returned as string values.View dimensions attributesClick or tap to expand
Physical, digital, or custom size information.View physical attributesClick or tap to expand
Physical measurements.
View media attributesClick or tap to expand
Product media shown during browsing and checkout.View prices attributesClick or tap to expand
Non-archived catalog prices currently attached to the product.View shipment attributesClick or tap to expand
How the product is delivered or fulfilled.View delivery detailsClick or tap to expand
Present for delivery fulfillment.View download detailsClick or tap to expand
Present for download fulfillment.View render detailsClick or tap to expand
Present for rendered fulfillment.View service detailsClick or tap to expand
Present for service fulfillment.View stream detailsClick or tap to expand
Present for streaming fulfillment.
variant_setobject|nullActive variant choices available to the customer. This can be omitted even whenallow_variantsistrue.Click or tap to expandView variant_axes attributesClick or tap to expand
View variants attributesClick or tap to expand
Products currently available as choices in the variant set.View price detailsClick or tap to expand
Resolved price for this variant, using the same shape as the top-levelpriceproperty.View product detailsClick or tap to expand
Hydrated catalog product for this variant, using the same shape as the top-levelproductproperty.View variant_values detailsClick or tap to expand
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.
AI clients can use create_buy_link for this operation. Confirmed MCP actions still require explicit form confirmation before Inttegro changes state.
Rules
- Send exactly one of
productorproduct_id. - Send exactly one of
priceorprice_id. - 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.valuemust be at least1and uses the smallest currency unit. Its currency is normalized to lowercase. - Within
price, send exactly one ofidornominal. For comparison pricing, send at most one oforiginalororiginal_id; withinoriginal, send exactly one ofidornominal. quantity.minis required and must be at least1.quantity.maxis optional. When present, it must be at least1and greater than or equal toquantity.min; when omitted, the offer has no upper quantity limit.expires_atmust be a future RFC3339 timestamp when provided.- A
product.variant_set_idis saved as offer configuration. Variant options are returned only when that set and its eligible products are available at lookup time. - Omit
usageor setmulti_use: truefor a reusable link. Setsingle_use: truefor a link that can create only one order. Do not send both fields.
Request attributes
priceobjectPrice configuration for the Buy link. Use this instead ofprice_idto supply an inline amount, a catalog price with comparison pricing, or both the sale and comparison amounts inline.Click or tap to expandView original attributesClick or tap to expand
Optional original price for strike-through pricing when you are supplying a custom nominal amount.
Request
- cURL
- TypeScript
- Go
- Python
- PHP
- Ruby
- Java
- C#
curl https://api.inttegro.com/purchase_intents/create \
-H "Authorization: Bearer $INTTEGRO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: buy-link-matcha-launch-001" \
-d '{
"product_id": "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
"price_id": "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
"quantity": {
"max": 5,
"min": 1
},
"usage": {
"multi_use": true
},
"expires_at": "2030-12-01T09:00:00Z"
}'
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",
quantity: {
max: 5,
min: 1,
},
usage: {
multiUse: true,
},
expiresAt: "2030-12-01T09:00:00Z",
})
package main
import (
"context"
"log"
"os"
inttegro "github.com/zebodotdev/inttegro-sdk-go/v4"
)
func main() {
ctx := context.Background()
client := inttegro.NewClient(os.Getenv("INTTEGRO_API_KEY"))
params := inttegro.CreatePurchaseIntentParams{
ProductID: "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
PriceID: "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
Quantity: inttegro.PurchaseIntentQuantity{
Max: 5,
Min: 1,
},
Usage: &inttegro.PurchaseIntentUsage{
MultiUse: inttegro.Bool(true),
},
ExpiresAt: "2030-12-01T09:00:00Z",
}
result, err := client.PurchaseIntents.Create(ctx, params)
if err != nil {
log.Fatal(err)
}
_ = result
}
import os
import inttegro
client = inttegro.InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])
result = client.purchase_intents.create(inttegro.purchase_intents.CreateRequest(
product_id="prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
price_id="pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
quantity=inttegro.purchase_intents.Quantity(
max=5,
min=1,
),
usage=inttegro.purchase_intents.Usage(
multi_use=True,
),
expires_at="2030-12-01T09:00:00Z",
))
<?php
use Inttegro\Client;
$client = new Client($_ENV['INTTEGRO_API_KEY']);
$result = $client->purchaseIntents->create([
'product_id' => 'prod_P9sK3vLm4nQ2xR7tY1wBc8Da',
'price_id' => 'pr_G6tV2nQ9xM4bR7cD1yKs5LpW',
'quantity' => [
'max' => 5,
'min' => 1,
],
'usage' => [
'multi_use' => true,
],
'expires_at' => '2030-12-01T09:00:00Z',
]);
require "inttegro"
client = Inttegro::Client.new(api_key: ENV.fetch("INTTEGRO_API_KEY"))
result = client.purchase_intents.create(
product_id: "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
price_id: "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
quantity: {
max: 5,
min: 1,
},
usage: {
multi_use: true,
},
expires_at: "2030-12-01T09:00:00Z"
)
import com.inttegro.Client;
import com.inttegro.purchaseintents.CreatePurchaseIntentParams;
import com.inttegro.purchaseintents.PurchaseIntentQuantity;
import com.inttegro.purchaseintents.PurchaseIntentUsage;
public class Example {
public static void main(String[] args) throws Exception {
var client = new Client(System.getenv("INTTEGRO_API_KEY"));
var params = CreatePurchaseIntentParams.builder()
.productId("prod_P9sK3vLm4nQ2xR7tY1wBc8Da")
.priceId("pr_G6tV2nQ9xM4bR7cD1yKs5LpW")
.quantity(PurchaseIntentQuantity.builder()
.max(5)
.min(1)
.build())
.usage(PurchaseIntentUsage.builder()
.multiUse(true)
.build())
.expiresAt("2030-12-01T09:00:00Z")
.build();
var result = client.purchaseIntents().create(params);
}
}
using Inttegro;
using var inttegro = new InttegroClient(
Environment.GetEnvironmentVariable("INTTEGRO_API_KEY")!
);
var result = await inttegro.PurchaseIntents.CreateAsync(new {
product_id = "prod_P9sK3vLm4nQ2xR7tY1wBc8Da",
price_id = "pr_G6tV2nQ9xM4bR7cD1yKs5LpW",
quantity = new {
max = 5,
min = 1,
},
usage = new {
multi_use = true,
},
expires_at = "2030-12-01T09:00:00Z",
});
Response
- Object
- JSON
PurchaseIntentResponse {
purchaseIntent: { … },
}
{
"purchase_intent": {
"id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
"application_id": "app_6RrJ4mQ2vBc8Y1pNs5tW3LxD",
"quantity": { … },
"allow_variants": false,
"usage": { … },
"expires_at": "2030-12-01T09:00:00Z",
"status": "active",
"created_at": "2026-08-05T12:00:00Z",
"product": { … },
"price": { … }
}
}
Update a purchase intent
Change the quantity or availability window 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.
AI clients can use update_buy_link for this operation. Confirmed MCP actions still require explicit form confirmation before Inttegro changes state.
Rules
- Send exactly one identifier. Use
idfor new integrations;purchase_intent_idremains available as a compatibility alias. expires_at: nullclears the expiry time.- A non-null
expires_atmust be an RFC3339 timestamp. A past timestamp is accepted and makes the offer immediately expired. reactivate: trueclears cancellation state and any existing elapsed expiry. If the same request sets a new elapsedexpires_at, the intent remains expired.- When supplied,
quantitymust includemin, which must be at least1. Its optionalmaxmust be greater than or equal tomin. - Omitting
quantity.maxremoves an existing upper quantity limit. Omit the entirequantityobject 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
Request
- cURL
- TypeScript
- Go
- Python
- PHP
- Ruby
- Java
- C#
curl https://api.inttegro.com/purchase_intents/update \
-H "Authorization: Bearer $INTTEGRO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: buy-link-matcha-update-001" \
-d '{
"id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
"quantity": { "min": 2, "max": 8 },
"reactivate": true
}'
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",
quantity: {
min: 2,
max: 8,
},
reactivate: true,
})
package main
import (
"context"
"log"
"os"
inttegro "github.com/zebodotdev/inttegro-sdk-go/v4"
)
func main() {
ctx := context.Background()
client := inttegro.NewClient(os.Getenv("INTTEGRO_API_KEY"))
params := inttegro.UpdatePurchaseIntentParams{
ID: "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
Quantity: &inttegro.PurchaseIntentQuantity{
Min: 2,
Max: 8,
},
Reactivate: inttegro.Bool(true),
}
result, err := client.PurchaseIntents.Update(ctx, params)
if err != nil {
log.Fatal(err)
}
_ = result
}
import os
import inttegro
client = inttegro.InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])
result = client.purchase_intents.update(inttegro.purchase_intents.UpdateRequest(
id="sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
quantity=inttegro.purchase_intents.UpdateQuantity(
min=2,
max=8,
),
reactivate=True,
))
<?php
use Inttegro\Client;
$client = new Client($_ENV['INTTEGRO_API_KEY']);
$result = $client->purchaseIntents->update([
'id' => 'sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha',
'quantity' => [
'min' => 2,
'max' => 8,
],
'reactivate' => true,
]);
require "inttegro"
client = Inttegro::Client.new(api_key: ENV.fetch("INTTEGRO_API_KEY"))
result = client.purchase_intents.update(
id: "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
quantity: {
min: 2,
max: 8,
},
reactivate: true
)
import com.inttegro.Client;
import com.inttegro.purchaseintents.UpdatePurchaseIntentParams;
import com.inttegro.purchaseintents.PurchaseIntentQuantity;
public class Example {
public static void main(String[] args) throws Exception {
var client = new Client(System.getenv("INTTEGRO_API_KEY"));
var params = UpdatePurchaseIntentParams.builder()
.id("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha")
.quantity(PurchaseIntentQuantity.builder()
.min(2)
.max(8)
.build())
.reactivate(true)
.build();
var result = client.purchaseIntents().update(params);
}
}
using Inttegro;
using var inttegro = new InttegroClient(
Environment.GetEnvironmentVariable("INTTEGRO_API_KEY")!
);
var result = await inttegro.PurchaseIntents.UpdateAsync(new {
id = "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
quantity = new {
min = 2,
max = 8,
},
reactivate = true,
});
Response
- Object
- JSON
PurchaseIntentResponse {
purchaseIntent: { … },
}
{
"purchase_intent": {
"id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
"application_id": "app_6RrJ4mQ2vBc8Y1pNs5tW3LxD",
"quantity": { … },
"allow_variants": false,
"usage": { … },
"expires_at": "2030-12-01T09:00:00Z",
"status": "active",
"created_at": "2026-08-05T12:00:00Z",
"updated_at": "2026-08-05T12:18:00Z",
"product": { … },
"price": { … }
}
}
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 status: "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.
AI clients can use cancel_buy_link for this operation. Confirmed MCP actions still require explicit form confirmation before Inttegro changes state.
Request attributes
Request
- cURL
- TypeScript
- Go
- Python
- PHP
- Ruby
- Java
- C#
curl https://api.inttegro.com/purchase_intents/cancel \
-H "Authorization: Bearer $INTTEGRO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: buy-link-matcha-cancel-001" \
-d '{
"id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha"
}'
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",
})
package main
import (
"context"
"log"
"os"
inttegro "github.com/zebodotdev/inttegro-sdk-go/v4"
)
func main() {
ctx := context.Background()
client := inttegro.NewClient(os.Getenv("INTTEGRO_API_KEY"))
result, err := client.PurchaseIntents.Cancel(ctx, "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha")
if err != nil {
log.Fatal(err)
}
_ = result
}
import os
import inttegro
client = inttegro.InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])
result = client.purchase_intents.cancel("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha")
<?php
use Inttegro\Client;
$client = new Client($_ENV['INTTEGRO_API_KEY']);
$result = $client->purchaseIntents->cancel("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha");
require "inttegro"
client = Inttegro::Client.new(api_key: ENV.fetch("INTTEGRO_API_KEY"))
result = client.purchase_intents.cancel(id: "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha")
import com.inttegro.Client;
public class Example {
public static void main(String[] args) throws Exception {
var client = new Client(System.getenv("INTTEGRO_API_KEY"));
var result = client.purchaseIntents().cancel("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha");
}
}
using Inttegro;
using var inttegro = new InttegroClient(
Environment.GetEnvironmentVariable("INTTEGRO_API_KEY")!
);
var result = await inttegro.PurchaseIntents.CancelAsync("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha");
Response
- Object
- JSON
PurchaseIntentResponse {
purchaseIntent: { … },
}
{
"purchase_intent": {
"id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
"application_id": "app_6RrJ4mQ2vBc8Y1pNs5tW3LxD",
"quantity": { … },
"allow_variants": false,
"usage": { … },
"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": { … },
"price": { … }
}
}
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 and recent activity.
AI clients can use get_buy_link for this operation. MCP read tools return minimized business data and do not change Inttegro state.
Required attributes
Request
- cURL
- TypeScript
- Go
- Python
- PHP
- Ruby
- Java
- C#
curl https://api.inttegro.com/purchase_intents/lookup \
-H "Content-Type: application/json" \
-d '{
"id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha"
}'
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",
})
package main
import (
"context"
"log"
"os"
inttegro "github.com/zebodotdev/inttegro-sdk-go/v4"
)
func main() {
ctx := context.Background()
client := inttegro.NewClient(os.Getenv("INTTEGRO_API_KEY"))
result, err := client.PurchaseIntents.Lookup(ctx, "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha")
if err != nil {
log.Fatal(err)
}
_ = result
}
import os
import inttegro
client = inttegro.InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])
result = client.purchase_intents.lookup("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha")
<?php
use Inttegro\Client;
$client = new Client($_ENV['INTTEGRO_API_KEY']);
$result = $client->purchaseIntents->lookup("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha");
require "inttegro"
client = Inttegro::Client.new(api_key: ENV.fetch("INTTEGRO_API_KEY"))
result = client.purchase_intents.lookup(id: "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha")
import com.inttegro.Client;
public class Example {
public static void main(String[] args) throws Exception {
var client = new Client(System.getenv("INTTEGRO_API_KEY"));
var result = client.purchaseIntents().lookup("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha");
}
}
using Inttegro;
using var inttegro = new InttegroClient(
Environment.GetEnvironmentVariable("INTTEGRO_API_KEY")!
);
var result = await inttegro.PurchaseIntents.LookupAsync("sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha");
Response
- Object
- JSON
PurchaseIntentResponse {
purchaseIntent: { … },
}
{
"purchase_intent": {
"id": "sale_B7tQ2nLm5yR8cV1pKs4Dx9Ha",
"application_id": "app_6RrJ4mQ2vBc8Y1pNs5tW3LxD",
"merchant": { … },
"quantity": { … },
"allow_variants": true,
"usage": { … },
"status": "active",
"created_at": "2026-08-05T12:00:00Z",
"product": { … },
"price": { … }
}
}
List purchase intents
Browse your Buy links, newest first. Each item contains the same merchant-facing details as an authenticated lookup and may include recent activity.
Pagination is numbered rather than cursor-based. page.size in the response is the number of intents actually returned, which can be smaller than the requested page_size. The response does not include a total count or next-page token.
AI clients can use list_buy_links for this operation. MCP read tools return minimized business data and do not change Inttegro state.
Required attributes
Request
- cURL
- TypeScript
- Go
- Python
- PHP
- Ruby
- Java
- C#
curl https://api.inttegro.com/purchase_intents/page \
-H "Authorization: Bearer $INTTEGRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"page_number": 1,
"page_size": 20
}'
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,
})
package main
import (
"context"
"log"
"os"
inttegro "github.com/zebodotdev/inttegro-sdk-go/v4"
)
func main() {
ctx := context.Background()
client := inttegro.NewClient(os.Getenv("INTTEGRO_API_KEY"))
params := inttegro.PagePurchaseIntentsParams{
PageNumber: 1,
PageSize: 20,
}
result, err := client.PurchaseIntents.Page(ctx, params)
if err != nil {
log.Fatal(err)
}
_ = result
}
import os
import inttegro
client = inttegro.InttegroClient(api_key=os.environ["INTTEGRO_API_KEY"])
result = client.purchase_intents.page(inttegro.purchase_intents.PageRequest(
page_number=1,
page_size=20,
))
<?php
use Inttegro\Client;
$client = new Client($_ENV['INTTEGRO_API_KEY']);
$result = $client->purchaseIntents->page([
'page_number' => 1,
'page_size' => 20,
]);
require "inttegro"
client = Inttegro::Client.new(api_key: ENV.fetch("INTTEGRO_API_KEY"))
result = client.purchase_intents.page(
page_number: 1,
page_size: 20
)
import com.inttegro.Client;
import com.inttegro.purchaseintents.PagePurchaseIntentsParams;
public class Example {
public static void main(String[] args) throws Exception {
var client = new Client(System.getenv("INTTEGRO_API_KEY"));
var params = PagePurchaseIntentsParams.builder()
.pageNumber(1)
.pageSize(20)
.build();
var result = client.purchaseIntents().page(params);
}
}
using Inttegro;
using var inttegro = new InttegroClient(
Environment.GetEnvironmentVariable("INTTEGRO_API_KEY")!
);
var result = await inttegro.PurchaseIntents.PageAsync(new {
page_number = 1,
page_size = 20,
});
Related resources
- Create a product - Build the catalog item a Buy link points at.
- Create a price - Store the catalog price a Buy link should reuse.
- Accept payment with Inttegro Checkout - Put the hosted checkout experience in front of customers.
- Create an order - Compare direct order creation with Buy-link-driven order creation.