---
title: Create Cart and Checkout Permalinks
description: >-
  Learn how to build Cart and Checkout Permalinks that turn a buyer's items,
  details, and discount codes into a cart or checkout.
source_url:
  html: 'https://shopify.dev/docs/agents/carts-and-checkout/permalinks'
  md: 'https://shopify.dev/docs/agents/carts-and-checkout/permalinks.md'
---

# Create Cart and Checkout Permalinks

Cart and Checkout Permalinks are links that turn what a buyer wants to buy into a cart or checkout on a merchant's store. By default, a permalink opens checkout with the items and buyer details from the link. You can send buyers to the cart or another store page instead. Opening the link never places an order or charges the buyer.

Cart and Checkout Permalinks are Shopify's implementation of the Universal Commerce Protocol (UCP) [permalink capability](https://ucp.dev/latest/specification/permalink/) (`dev.ucp.shopping.permalink`), and the successor to [legacy cart permalinks](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks). Shopify hosts the permalink endpoint and lists it in the store's profile, so merchants don't need to set it up.

Your agent or app builds the link and gives it to the buyer without managing a cart. A permalink is a browser link, not an API request, so it doesn't return a cart ID or totals to your app.

***

## What you'll learn

In this tutorial, you'll learn how to do the following tasks:

* Find a store's permalink endpoint.
* Build a permalink with one or more items.
* Add buyer details, a shipping address, the country and language, and discount codes.
* Add marketing attribution.
* Choose where the buyer lands.
* Test a permalink, and check what happens when Shopify can't use part of it.

***

## Requirements

* Get the product variant IDs for the items that you want to sell. [Global Catalog](https://shopify.dev/docs/agents/catalog/global-catalog) and [Storefront Catalog](https://shopify.dev/docs/agents/catalog/storefront-catalog) return them for each product.

***

## Step 1: Find the permalink endpoint

A store lists the `dev.ucp.shopping.permalink` capability in its [business profile](https://ucp.dev/latest/specification/overview/) at `/.well-known/ucp`. The capability's `config.endpoint` value is the base URL for every permalink that you build for that store. The following example shows the permalink and cart capabilities from a profile, where `{version}` is Shopify's current default UCP version, such as `2026-08-25`:

## {shop}.example.com/.well-known/ucp

```json
{
  "ucp": {
    "version": "{version}",
    "capabilities": {
      "dev.ucp.shopping.cart": [
        {
          "version": "{version}",
          "spec": "https://ucp.dev/{version}/specification/shopping/cart/",
          "schema": "https://ucp.dev/{version}/schemas/shopping/cart.json"
        }
      ],
      "dev.ucp.shopping.permalink": [
        {
          "version": "{version}",
          "spec": "https://ucp.dev/{version}/specification/permalink/",
          "schema": "https://ucp.dev/{version}/schemas/shopping/permalink.json",
          "config": {
            "endpoint": "https://{shop}.example.com/buy"
          }
        }
      ]
    }
  }
}
```

Keep the following in mind:

* Use the endpoint exactly as the profile lists it, instead of building it yourself. It's usually on the store's primary domain, but a store without an online store uses its `myshopify.com` domain.
* The endpoint creates carts only for a store that sells through the online store, a headless channel, or Shopify Catalog. If a store has none of these sales channels, then Shopify sends the buyer to the store's home page without a cart. For these stores, use [legacy cart permalinks](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks) instead. Send the link to a headless storefront that supports cart permalinks, or add a [storefront access token](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks#step-4-attribute-an-order-to-a-sales-channel) for a sales channel that sells the items.
* If the profile doesn't list `dev.ucp.shopping.permalink`, then the store doesn't accept Cart and Checkout Permalinks. Use [legacy cart permalinks](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks) instead.
* The profile lists every capability that the store supports, with a link to each schema. The fields that you can add to a permalink come from the cart schema, plus the schemas of cart extensions such as `dev.ucp.shopping.discount` and `dev.ucp.shopping.fulfillment`.
* If a link doesn't set a UCP version, then Shopify uses its current default version, which moves to newer versions over time. To keep a link working the same way, add the version that you built it for to the query string, such as `ucp/version=2026-08-25`.

***

## Step 2: Add items

Add the items to the end of the endpoint as a comma-separated list of `{variant_id}:{quantity}` pairs. The following example adds one of variant `70881412` and two of variant `70881382`:

```text
https://{shop}.example.com/buy/70881412:1,70881382:2
```

You can use the numeric variant ID or the full variant GID. A GID contains characters that can't go in the path, so encode it as `~` followed by the GID in base64url, without padding. For example, `gid://shopify/ProductVariant/70881412` becomes the following item:

```text
https://{shop}.example.com/buy/~Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC83MDg4MTQxMg:1
```

Keep the following rules in mind:

* A link needs at least one item.
* Every item needs a quantity. Use a whole number greater than zero, without leading zeros.
* If an item is sold out or doesn't have enough stock, then Shopify adds only the quantity that's available, or leaves the item out. If Shopify can't add an item for any other reason, then it doesn't create the cart, even for the other items. To learn where the buyer lands when Shopify doesn't create a cart, refer to [Step 6](#step-6-test-the-permalink).
* A link can have up to 500 items, and the full URL can be up to 2,048 bytes. Links for QR codes, print, and text messages work best when they're much shorter. For recommended sizes, refer to [URL budget](https://ucp.dev/latest/specification/permalink/#url-budget) in the UCP permalink specification.
* Each time a buyer opens the link, Shopify creates a new cart with only the link's items. The new cart replaces any cart that the buyer already had on the store.

***

## Step 3 (Optional): Add buyer and cart details

Add [fields as query parameters](https://ucp.dev/latest/specification/permalink/#ucp-fields) to prefill the buyer's details, set their country and language, and add discount codes.

Each parameter name is the path to a field in the cart or extension schemas from [Step 1](#step-1-find-the-permalink-endpoint), with a `/` between each level (for example, `buyer/email`). For lists, use each entry's position, starting at `0` (for example, `discounts/codes/0` and `discounts/codes/1`). Don't skip a number, and add each field only once. If a link has the same field more than once, then Shopify ignores all the buyer and cart details in the link, and creates the cart with only the items.

The table below is a non-exhaustive list of fields you can add. Shopify ignores any field that it doesn't support, and applies the rest of the link.

| Field | Description |
| - | - |
| `buyer/email` | The buyer's email address. |
| `buyer/phone_number` | The buyer's phone number in E.164 format (for example, `+18005550123`). |
| `context/address_country` | The buyer's country, as an uppercase two-letter code (for example, `US`). Shopify uses it to set the cart's country and currency. |
| `context/language` | The buyer's language, as an IETF BCP 47 tag (for example, `fr` or `fr-CA`). Checkout uses this language if the store has published it. |
| `context/payment/0/handler` | Set to `dev.shopify.shop_pay` to request Shop Pay checkout. The store must accept Shop Pay and the checkout must be eligible. Shopify ignores other handlers. |
| `fulfillment/methods/0/type` | Set to `shipping` to add a shipping address. |
| `fulfillment/methods/0/destinations/0/{field}` | A [shipping address field](https://ucp.dev/latest/specification/reference/#postal-address), such as `street_address`. |
| `discounts/codes/{index}` | A discount code. |

URL-encode (percent-encode) each value. Shopify reads an unencoded `+` as a space, so send a phone number such as `+18005550123` as `%2B18005550123`.

The following example prefills the buyer's email address and adds a discount code:

```text
https://{shop}.example.com/buy/70881412:1?buyer/email=sasha%40example.com&discounts/codes/0=WELCOME10
```

The buyer can change any prefilled value in checkout.

**Caution:**

Links with buyer details are personal. Send them only to that buyer, and don't use them in QR codes, public posts, or campaigns. To learn more, refer to [Privacy](https://ucp.dev/latest/specification/permalink/#privacy) in the UCP permalink specification.

***

## Step 4 (Optional): Add marketing attribution

Shopify supports only the following marketing attribution fields:

| Permalink fields | Value to pass |
| - | - |
| `attribution/utm_source` `attribution/utm_medium` `attribution/utm_campaign` `attribution/utm_content` `attribution/utm_term` | The original value of the UTM parameter with the same name, such as `google` for `utm_source`. |
| `attribution/referring_domain` | The referring website's domain, such as `example.com`. |
| `attribution/click_id_tag` `attribution/click_id_value` | The original click ID parameter name, such as `gclid`, `fbclid`, or `shclid`, and its value. |
| `attribution/activity_id_tag` `attribution/activity_id_value` | The original marketing activity parameter name, such as `shcgid` for a Catalog ID, and its value. |

For a click ID or activity ID, put the original query parameter name in the tag field and its value in the value field. A permalink can carry one click ID pair and one activity ID pair. The following example adds UTM values and a Google Ads click ID:

```text
https://{shop}.example.com/buy/70881412:1?attribution/utm_source=google&attribution/utm_medium=cpc&attribution/click_id_tag=gclid&attribution/click_id_value={click_id}
```

***

## Step 5 (Optional): Choose where the buyer lands

By default, Shopify sends the buyer to checkout. To send them to another page on the store, add `continue_to` with the page's path. For example, the following link sends the buyer to their cart:

```text
https://{shop}.example.com/buy/70881412:1?continue_to=/cart
```

Shopify checks the path before it redirects the buyer:

* The path must start with a single `/`. Shopify doesn't follow full URLs, including URLs for the store's other domains.
* Shopify removes any query string or fragment from the path. For example, `/collections/all?sort_by=price-ascending` sends the buyer to `/collections/all`.
* If `continue_to` isn't valid or appears more than once, then Shopify sends the buyer to checkout.

***

## Step 6: Test the permalink

Before you share the permalink, open it in a browser and check the items, prefilled details, and destination.

If the link is invalid or Shopify can't create the cart, then Shopify sends the buyer to a valid `continue_to` path or the store's home page. Shopify ignores `continue_to` and sends the buyer to the home page when the link is over 2,048 bytes, or when the store can't accept permalinks, such as a store without the online store, a headless channel, or Shopify Catalog. Shopify can still create a cart when it can't apply a field, such as a discount code.

Some failures return an HTTP error instead of a redirect. Incorrect percent-encoding can return a `400 Bad Request` error. A temporary problem, such as rate limiting or a timeout, can return an error such as `429 Too Many Requests` or `504 Gateway Timeout`.

Shopify creates the cart only when the buyer opens the link. It doesn't create a cart when a browser prefetches or prerenders the link. If the store uses bot protection for an item, then Shopify might ask the buyer to complete a verification step before it creates the cart.

***

## Limitations

Cart and Checkout Permalinks don't support the following features yet:

* **Sales channel attribution:** You can't add a storefront access token or `source_name`, so Shopify can't attribute orders to your sales channel.
* **Other query parameters:** Shopify ignores query parameters that aren't UCP fields, such as `utm_source` or `gclid` without the `attribution/` prefix. To keep marketing attribution, use the fields in [Step 4](#step-4-optional-add-marketing-attribution).
* **Selling plans:** Shopify adds every item as a one-time purchase, and ignores `line_items/{index}/selling_plan`. If an item requires a [selling plan](https://shopify.dev/docs/apps/build/purchase-options/subscriptions/selling-plans), such as a subscription-only product, then Shopify can't create the cart.
* **Notes, attributes, and properties:** You can't add a cart note, cart attributes, line item properties, or a `ref` referral code.

If you need sales channel attribution, a cart note, cart attributes, line item properties, or a `ref` referral code, then use [legacy cart permalinks](https://shopify.dev/docs/apps/build/checkout/create-cart-permalinks) for that link. Neither option supports selling plans.

***

## Next steps

* Use [Cart MCP](https://shopify.dev/docs/agents/carts-and-checkout/cart-mcp) when your agent needs to show totals or change items before it hands off to checkout.
* Read the [UCP permalink specification](https://ucp.dev/latest/specification/permalink/) for the full link format.

***
