Use read_gift_cards to read settings, limits and card details, and write_gift_cards to issue or update cards. Codes are shown only at issuance; keep them secret and never log them. Use the supported currency precision and limits returned by the API.
Delivery availability is checked again when issuing. Configure the selected provider and its Gift Card template before phone delivery. Provider submission is not proof of receipt; use provider reports when receipt is uncertain. Retry only attempts returned with can_retry: true.
Card details include delivery attempts, balance movements and lifecycle history. Older cards retain known issuance and activation dates; earlier changes are not reconstructed. Refunds to the original card require a usable card. Expired, disabled and cancelled cards cannot receive a new refund credit.
Endpoints#
List Gift Card products
Find catalog products that issue Gift Cards after payment.
Uses the product cursor pagination, search and sorting contract. These are products, not issued codes or balances. Read/edit a product using /products/{id}. Product detail includes is_gift_card and gift_card_policy (can_edit_value, can_delete, and a localized reason when locked).
Query parameters
| Name | Type | Description |
|---|---|---|
cursor
|
string |
Opaque cursor from a previous |
limit
|
integer |
Page size from 1 to |
status
|
string |
Filter: active, scheduled, draft, or archived. |
type
|
string |
Filter: simple or variable. |
ids
|
string |
Comma-separated product IDs, up to |
category_id
|
integer |
Filter by assigned category ID. |
category_ids
|
string |
Comma-separated category IDs; matches products in any listed category. |
vendor_id
|
integer |
Filter by assigned vendor ID. |
vendor_ids
|
string |
Comma-separated vendor IDs; matches any listed vendor. |
brand_id
|
integer |
Filter by assigned brand ID. |
brand_ids
|
string |
Comma-separated brand IDs; matches any listed brand. |
tag_id
|
integer |
Filter by assigned tag ID. |
tag_ids
|
string |
Comma-separated assigned tag IDs. Use |
tag_match
|
string |
How |
collection_id
|
uuid |
Filter by manual or automatic collection membership. |
collection_ids
|
string |
Comma-separated collection UUIDs; matches membership in any listed collection. |
location_id
|
uuid |
Filter to products with inventory at this location. |
location_ids
|
string |
Comma-separated location UUIDs; matches inventory at any listed location. |
low_stock_only
|
boolean |
Return products at or below a configured low-stock threshold. |
stock_min
|
integer |
Minimum displayed available stock. Untracked products do not match. |
stock_max
|
integer |
Maximum displayed available stock. Untracked products do not match. |
price_min
|
decimal string |
Minimum regular price in the store currency. |
price_max
|
decimal string |
Maximum regular price in the store currency. |
search
|
string |
Search text; surrounding whitespace is removed. Text exceeding |
search_field
|
string |
Defaults to |
sort_by
|
string |
A value from |
sort_direction
|
string |
|
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
401UNAUTHORIZEDMissing or invalid Store API token.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the read_products scope.
-
400INVALID_INPUTA query parameter is invalid. Boolean filters accept only
trueorfalse.
Create a Gift Card product
Create a single-value Gift Card catalog product.
Send type: simple, a positive regular price, an SKU, status and explicit channel_ids. Draft products and products without channels are not purchasable. No physical stock, shipping, tax classes, sale prices, quantity discounts or free-gift settings. Updates and deletion use /products/{id} and also require write_gift_cards. Once an order references the product (even unpaid), financial edits and deletion fail with GIFT_CARD_PRODUCT_LOCKED; archive or unpublish instead. Existing issued cards are unchanged by catalog edits. Existing variable Gift Card products remain readable and purchasable. Product webhooks use the ordinary product topics and is_gift_card; issued-card events use the separate Gift Card topics.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
title
required
|
string |
Product title. Required on create; cannot be empty on update. Normalized to NFC. Control characters are rejected. See title_max_length in GET /products/limits. |
slug
|
string |
URL slug. Omit on create to generate it from the title. A source slug must use lowercase, hyphen-separated words and stay within slug_max_length. A duplicate source slug receives a suffix. On update, omit to keep it; changing it creates a redirect unless create_redirect is false. |
type
required
|
string |
Required on create: simple or variable. Cannot be changed after creation. Allowed values: |
status
|
string |
Product status: draft, active, scheduled, or archived. Defaults to draft. Scheduled products require publish_at. Active products are available only through their assigned sales channels. Allowed values: |
publish_at
|
string |
Publication time, required when the resulting status is scheduled. Accepts an ISO 8601 timestamp; include an offset for an explicit instant, or use the store timezone for a local timestamp. Stay within publish_max_days_ahead from GET /products/limits. Invalid local times during a daylight-saving change are rejected; a repeated local time uses its first occurrence. Changing to another status clears the schedule. |
description
|
string |
Rich HTML description. Unsafe HTML is removed. The sanitized HTML, including markup, must fit description_max_length. |
short_description
|
string |
Plain-text summary. Surrounding whitespace is removed and control characters are rejected. See short_description_max_length. |
vendor_id
|
integer |
Vendor ID in this store. On create, omit if unassigned. On update, omit or send null to keep the assignment; send 0 to clear it. |
brand_id
|
integer |
Brand ID in this store. On create, omit if unassigned. On update, omit or send null to keep the assignment; send 0 to clear it. |
category_ids
|
array |
Category IDs in this store, up to max_categories. Duplicates are removed. On update, replaces the assignment set; [] clears it and omission keeps it. |
tag_ids
|
array |
Tag IDs in this store, up to max_tags. Duplicates are removed. On update, replaces the assignment set; [] clears it and omission keeps it. |
channel_ids
|
array |
Sales-channel IDs in this store. Omission on create leaves the product unassigned. On update, replaces the assignment set; [] clears it and omission keeps it. |
attribute_ids
|
array |
Attribute IDs that define the variant combinations. Required for variable products. Each variant must provide one value per declared attribute. On update, replaces the declaration, subject to the surviving variants and store limits. Variable products only. |
seo_title
|
string |
Search-engine title. Whitespace is trimmed and control characters are rejected. See seo_title_max_length. |
seo_description
|
string |
Search-engine description. Whitespace is trimmed and control characters are rejected. See seo_description_max_length. |
template_handle
|
string |
Existing product template handle for this store. Use default_product for the default template. Omit on update to keep the assignment; an empty string is invalid. |
sku
required
|
string |
Required product SKU, including for a variable parent. ASCII letters, digits, hyphens, underscores, periods, and slashes are accepted. Trimmed, case-sensitive, and unique across products, variants, and inventory groups in the store. Case-only matches produce warnings. See sku_max_length. |
barcode
|
string |
Optional Barcode/GTIN for a simple product; variable products use variant barcodes. ASCII letters, digits, and hyphens are accepted. Must be unique across products and variants. See barcode_max_length. Simple products only. |
condition
|
string |
Merchandise condition. Defaults to new. Variants may override the parent condition. Allowed values: |
mpn
|
string |
Optional manufacturer part number. Not required to be unique. See mpn_max_length. |
no_manufacturer_identifiers
|
boolean |
Set true only if the product has no manufacturer identifiers. Cannot be true with a barcode or MPN. The response’s identifier_status is provided when identifiers exist, not_applicable when this flag is true, and unknown otherwise. |
gift_only
|
boolean |
Defaults to false. When true, direct cart additions are rejected with CART_GIFT_ONLY; the product can be added only as an eligible free gift. This flag does not hide the product from listings. |
hide_from_listings
|
boolean |
Defaults to false. Excludes the product from storefront search and browse listings while keeping its assigned-channel product page accessible by direct link. Does not change gift_only or channel assignments. |
requires_shipping
|
boolean |
Defaults to true and can be changed on update. Variants follow this value unless they set their own requires_shipping. While it is false, the product and every variant that follows it reject weight, dimensions, customs fields, and per-item shipping prices; values stored earlier are kept but not used. |
weight
|
number |
Positive weight within the store’s limit. Requires weight_unit. |
weight_unit
|
string |
Weight unit; required with weight. Allowed values: |
length
|
number |
Positive package length within the store’s limit. |
width
|
number |
Positive package width within the store’s limit. |
height
|
number |
Positive package height within the store’s limit. |
dimension_unit
|
string |
Dimension unit; required when any dimension is supplied. Allowed values: |
hs_code
|
string |
Customs HS code. See hs_code_max_length and the field constraints in GET /products/limits. |
country_of_origin
|
string |
Two-letter ISO country code. |
inventory_source
|
string |
Simple-product inventory mode: track for per-location stock, none for untracked stock, or group for an inventory-group link. Defaults to track. Changing modes on update may require confirmation. Allowed values: |
inventory_group_id
|
string |
Inventory-group UUID. Required with inventory_source=group. The group must belong to this store. Simple products only. |
max_order_quantity
|
integer |
Optional per-order quantity cap, independent of inventory mode. On update, 0 clears the explicit cap; omission or null leaves it unchanged. Without an explicit cap, the store’s default order cap may still apply. |
overall_low_stock_threshold
|
integer |
Overall low-stock threshold for directly tracked simple products. Uses total available stock across locations. Zero is valid. On update, null disables the alert and omission keeps it. Not available for untracked or group-backed stock. Simple products only. |
prices
|
array |
Simple products only. Rows are {currency_code, regular_price, sale_price?, cost_price?, sale_starts_at?, sale_ends_at?}. Amounts are JSON decimal strings with the currency’s permitted precision. Include the base currency. On update, supplying this array replaces the complete price set. A sale price may be zero but must be below the regular price. The base-currency sale schedule applies to all currency sale prices; a non-base sale requires a base sale. Omit sale prices from the replacement set to remove them. |
shipping_prices
|
array |
Simple products only. Per-currency flat shipping overrides: {currency_code, price}. Send price as an exact decimal string using that currency's precision. |
images
|
array |
Gallery entries: {file_id, alt_text?, sort_order?}. Files may be images, videos, or 3D models. Non-empty file_id values require read_files. On update, the array replaces the gallery; [] clears it. The store’s max_images limit applies. |
inventory
|
array |
Simple products with inventory_source=track. Rows are {location_id, quantity, low_stock_threshold?, expected_quantity?}. Quantities are non-negative integers within the store’s limits. On update, only named locations change. expected_quantity is the on-hand value previously read (0 for a missing row); a mismatch returns 409 PRODUCT_VERSION_STALE. You may use merchant-managed locations or locations owned by your app’s active installation. |
tax_classes
|
array |
Per-market tax assignment: {market_id, tax_class_id}. Supplied array replaces the full set. |
metafields
|
array |
Values as {definition_id, value}. Definitions must target products and permit your app to write them. On update, this array replaces the set your app can write; [] clears that set. Use the dedicated metafield endpoint for writes addressed by namespace and key. |
variants
|
array |
Variable products only; required (at least one variant). The initial variant set, validated together: combination uniqueness against the declared attributes, attribute coverage, at least one variant, and store-wide SKU uniqueness. Each entry:
Create supplies the initial set here. Later edits use the delta fields on Product update; read operations use the paginated Variant endpoints. |
Errors
-
409GIFT_CARD_PRODUCT_LOCKEDThe Gift Card product has an order reference. Omit financial fields when editing merchandising; archive instead of deleting.
-
409GIFT_CARD_PRODUCT_CONTROLS_INVALIDGift Card products do not support physical stock, shipping, tax classes, sale prices, quantity discounts or free-gift controls.
-
401UNAUTHORIZEDMissing or invalid Store API token.
-
403STORE_API_SCOPE_REQUIREDToken is valid but lacks the write_products scope.
-
403STORE_API_SCOPE_REQUIREDA non-empty images[] file_id or variant image_file_id requires read_files scope in addition to write_products.
-
404PRODUCT_NOT_FOUNDNo product with this ID in the store.
-
400INVALID_INPUTThe request shape or one of its field values is invalid. Money values must be JSON decimal strings and fit the referenced currency's precision.
-
400PRODUCT_PRICE_SET_REQUIREDA supplied Product or Variant price set is empty. Supply the complete set, including the store base currency.
-
400PRODUCT_VARIANT_DUPLICATE_UPDATE_IDThe same Variant ID appears more than once in one Product update.
-
400PRODUCT_VARIANT_DUPLICATE_COMBINATIONTwo surviving or concurrently updated Variants resolve to the same attribute combination.
-
400PRODUCT_MARKET_OR_TAX_CLASS_INVALIDA tax-class assignment does not belong to the Product's store and market.
-
409PRODUCT_VERSION_STALEAnother Product write committed after validation began. Reload and retry against the current Product.
Get Gift Card limits
Read Gift Card limits.
Returns issuance, recipient-field, search, pagination, and per-order limits. Use these values for client-side validation.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Get Gift Card settings
Read Gift Card checkout and expiry settings.
Returns checkout acceptance, paid-order expiry defaults and delivery_options (manual, email, phone). Availability can change; issuance validates the selected method again. Phone availability does not attest provider-specific template approval.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Update Gift Card settings
Change Gift Card checkout and expiry settings.
Updates the store's Gift Card settings. Omitted defaults are not inferred: send the complete settings object returned by the read endpoint.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
enabled
required
|
boolean |
Accept Gift Cards at checkout. |
expires_enabled
required
|
boolean |
Apply automatic expiry to cards from paid orders. |
expires_after_days
|
integer |
Days until cards from paid orders expire. |
max_cards_per_order
required
|
integer |
Maximum Gift Cards accepted on one order. |
Errors
-
400GIFT_CARD_INVALIDId is not a valid UUID.
-
404GIFT_CARD_NOT_FOUNDGift Card does not exist in this store.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
409GIFT_CARD_IDEMPOTENCY_CONFLICTThe idempotency key belongs to a different issuance.
-
400GIFT_CARD_CODE_NOT_REDEEMABLEThe card's lifecycle state does not allow this change.
List Gift Cards
List Gift Cards issued by the store.
Returns masked codes only. Filter by lifecycle status, issuance source, or currency, and search by the last four code characters or recipient.
Query parameters
| Name | Type | Description |
|---|---|---|
page
|
integer |
Page number. |
limit
|
integer |
Page size. |
search
|
string |
Last four code characters, recipient name, or recipient email. |
status
|
string |
Lifecycle status. |
source
|
string |
Issuance source: |
currency_code
|
string |
ISO 4217 currency code. |
sort_by
|
string |
Sort field from |
sort_direction
|
string |
|
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400VALIDATION_LIST_INVALID_PAGEPage must be positive.
-
400VALIDATION_LIST_INVALID_LIMITLimit is outside the Gift Card range.
-
400GIFT_CARD_INVALIDA filter, sort, or search value is invalid.
Issue a Gift Card
Issue a Gift Card manually.
The complete bearer code is returned when this request creates the card. Send Idempotency-Key: repeating the same request with the same details within an hour returns the card and its code again, so a lost response doesn't lose the code; after that, a repeat returns the card without its code. Reusing the key with different details returns GIFT_CARD_IDEMPOTENCY_CONFLICT. Webhook payloads never contain the code.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
currency_code
required
|
string |
ISO 4217 currency code: the store's base currency or another currency enabled in Settings > Currencies. |
amount
required
|
decimal string |
Initial value in the selected currency. |
reason
required
|
string |
Merchant-visible issuance reason. |
recipient_name
|
string |
Recipient name. |
recipient_email
|
string |
Recipient email. |
recipient_phone
|
string |
Validated international phone number including its calling code. |
recipient_message
|
string |
Message sent with the card. |
scheduled_at
|
datetime |
Future delivery and activation time. |
expires_at
|
datetime |
Future expiry time, later than scheduled_at when both are present. |
delivery_method
|
string |
Choose manual, email or phone from delivery_options. Manual does not send and cannot be scheduled. Email and phone require the corresponding recipient. |
recipient_customer_id
|
string |
Links the card to an existing customer of this store. Requires the |
Errors
-
401UNAUTHORIZEDAuthorization header missing, malformed, or token invalid/expired.
-
402SUBSCRIPTION_REQUIREDThe store does not have an active or trialing subscription.
-
403STORE_API_SCOPE_REQUIREDThe token lacks
write_gift_cards, or a non-emptyrecipient_customer_idwas sent withoutread_customers. -
429RATE_LIMITEDThe token's request allowance is exhausted. Retry after the Retry-After header.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400GIFT_CARD_INVALIDIdempotency-Keyis missing, or a value is invalid: the amount, a recipient field, the delivery method, the schedule or expiry, or a limit from Get Gift Card limits. -
400GIFT_CARD_CURRENCY_NOT_ENABLEDcurrency_code is neither the store's base currency nor an enabled store currency.
-
404STOREFRONT_CUSTOMER_NOT_FOUND_MSGrecipient_customer_id is not an active customer of this store.
-
409GIFT_CARD_IDEMPOTENCY_CONFLICTThe idempotency key was already used to issue a card with different details.
Get a Gift Card
Read one Gift Card.
Returns the store-scoped card with a masked code, current balance, recipient, delivery schedule and lifecycle dates. Detail responses include the first page of events, deliveries and movements, newest first, with events_next_cursor, deliveries_next_cursor and movements_next_cursor present only while that section has older entries. Read further pages from /gift-cards/{id}/history. An event has id, kind and created_at. A delivery has id, channel, destination, status, attempts, last_error_code, last_error_message, can_retry, created_at and updated_at. last_error_message is localized by the API for the request language; clients should display it directly and may use last_error_code only for machine-readable diagnostics. The deprecated last_error code alias remains during compatibility rollout. Movement fields are id, kind, amount, formatted_amount and created_at. Phone deliveries may also include provider_status (pending, processing, succeeded, failed), describing submission to the provider. Submission is not a customer-delivery receipt.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
string |
Gift Card UUID. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400GIFT_CARD_INVALIDId is not a valid UUID.
-
404GIFT_CARD_NOT_FOUNDGift Card does not exist in this store.
List Gift Card history
Page one section of a Gift Card's history.
Returns one page of events, deliveries or movements, newest first, in the same shape as the detail response. Pass the section's next_cursor from the detail response or the previous page as cursor; next_cursor is null on the last page. limit defaults to 20 and cannot exceed 50. A cursor is only valid for the card and section that issued it.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
string |
Gift Card UUID. |
Query parameters
| Name | Type | Description |
|---|---|---|
section
required
|
string |
History section: |
cursor
|
string |
The |
limit
|
integer |
Page size, 1 to 50. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Errors
-
400GIFT_CARD_INVALIDId is not a valid UUID.
-
404GIFT_CARD_NOT_FOUNDGift Card does not exist in this store.
-
400VALIDATION_LIST_INVALID_LIMITLimit is outside the history page range.
-
400GIFT_CARD_INVALIDSection is not events, deliveries or movements.
-
400GIFT_CARD_HISTORY_CURSOR_INVALIDCursor is malformed or belongs to another card or section.
Update a Gift Card
Update recipient, delivery, or expiry details.
Omitted fields remain unchanged. Use the clear flags to remove a delivery schedule or expiry. Expired, depleted and cancelled cards cannot be edited. Recipient and schedule changes are rejected after delivery starts. Send retry_delivery_id only for a delivery whose can_retry is true; correct its setup first. A retry retains the card and balance. Repeating a consumed retry is rejected without creating another attempt.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
string |
Gift Card UUID. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
recipient_name
|
string |
Recipient name. |
recipient_email
|
string |
Recipient email. |
recipient_phone
|
string |
Validated international phone number including its calling code. |
recipient_message
|
string |
Message sent with the card. |
delivery_scheduled_at
|
datetime |
Future delivery and activation time. |
expires_at
|
datetime |
Future expiry time, later than scheduled_at when both are present. |
retry_delivery_id
|
string |
ID of a delivery eligible for retry. Does not issue another card. |
clear_delivery_schedule
|
boolean |
Remove the delivery schedule. |
clear_expiry
|
boolean |
Remove the expiry. |
Errors
-
400GIFT_CARD_INVALIDId is not a valid UUID.
-
404GIFT_CARD_NOT_FOUNDGift Card does not exist in this store.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
409GIFT_CARD_IDEMPOTENCY_CONFLICTThe idempotency key belongs to a different issuance.
-
400GIFT_CARD_CODE_NOT_REDEEMABLEThe card's lifecycle state does not allow this change.
-
409GIFT_CARD_REFUND_PENDINGA refund of the order that sold this card is in progress; try again when it finishes.
Change Gift Card status
Activate, disable, or cancel a Gift Card.
Send Idempotency-Key and a reason. Cancelling permanently revokes the remaining balance; disabling pauses redemption and can be reversed by activating the card.
Path parameters
| Name | Type | Description |
|---|---|---|
id
required
|
string |
Gift Card UUID. |
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
status
required
|
string |
New status: |
reason
required
|
string |
Merchant-visible reason recorded in the audit log. |
Errors
-
400GIFT_CARD_INVALIDId is not a valid UUID.
-
404GIFT_CARD_NOT_FOUNDGift Card does not exist in this store.
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
409GIFT_CARD_IDEMPOTENCY_CONFLICTThe idempotency key belongs to a different issuance.
-
400GIFT_CARD_CODE_NOT_REDEEMABLEThe card's lifecycle state does not allow this change.
-
409GIFT_CARD_REFUND_PENDINGA refund of the order that sold this card is in progress; try again when it finishes.
Change Gift Card statuses
Activate or disable many Gift Cards.
Send Idempotency-Key, up to bulk_max_count distinct card ids, a status of active or disabled, and a reason. Each card changes independently: updated lists the cards that now have the requested status and failed lists each card that could not change with its error code and localized message, so one refused card never blocks the others. Repeating the request with the same key does not repeat a change that already applied. Cancelling is permanent and is only available one card at a time through the single-card status endpoint.
Headers
| Name | Type | Description |
|---|---|---|
Authorization
required
|
string |
Bearer Store API token. |
Body parameters
| Name | Type | Description |
|---|---|---|
ids
required
|
array<string> |
Gift Card UUIDs, 1 to |
status
required
|
string |
New status: |
reason
required
|
string |
Merchant-visible reason recorded in each card's audit log. |
Errors
-
400STORE_API_INVALID_REQUEST_BODYRequest body is not valid JSON.
-
400INVALID_INPUTA body field has the wrong JSON type.
-
400GIFT_CARD_INVALIDIdempotency-Keyis missing, or the ids, status or reason are invalid.