Products
48 endpoints. Each needs an API key or OAuth token with the scope shown; the key already names its store, so paths start at /v1/store. Generated from the live contract; also in openapi.json.
Products with tab counts
/v1/store/productsOr name the store: GET /v1/stores/{storeId}/products
Parameters
tab"all" | "active" | "draft" | "archived" | "low_stock" | "files" | "keys_and_serials" | "memberships" | "services" | "bundles"queryqstring | nullquerycursorstring | nullquerylimitinteger | stringquerytype"file" | "license_key" | "serial" | "subscription" | "discord_role" | "service" | "bundle" | nullqueryidsstring | nullquerycategorypcat_… | nullquerycollectioncol_… | nullquerysort"created" | "name" | "type" | "price" | "stock" | "sold" | "revenue" | "status" | "updated" | "manual"querydir"asc" | "desc"query
Response ListProductsResponse
itemsProduct[]requirednextCursorCursor | nullrequiredcountsProductCountsrequired
Example
curl "https://api.shopfa.st/v1/store/products" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Create a product
/v1/store/productsOr name the store: POST /v1/stores/{storeId}/products
Body
namestringrequiredtype"file" | "license_key" | "serial" | "subscription" | "discord_role" | "service" | "bundle"requiredpriceMinorintegerrequiredcompareAtMinorinteger | nullrequireddescriptionstringrequireddeliversstringrequiredstatus"active" | "draft" | "archived"requiredlowStockThresholdintegerrequired
Response Product
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
15 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
}'const res = await fetch('https://api.shopfa.st/v1/store/products', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products", strings.NewReader(`{
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
One product
/v1/store/products/{productId}Or name the store: GET /v1/stores/{storeId}/products/{productId}
Parameters
productIdprd_…pathrequired
Response Product
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
15 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Update a product
/v1/store/products/{productId}Or name the store: PATCH /v1/stores/{storeId}/products/{productId}
Parameters
productIdprd_…pathrequired
Body
namestringtype"file" | "license_key" | "serial" | "subscription" | "discord_role" | "service" | "bundle"priceMinorintegercompareAtMinorinteger | nulldescriptionstringdeliversstringstatus"active" | "draft" | "archived"lowStockThresholdinteger
Response Product
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
15 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequired
Example
curl -X PATCH "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PATCH",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PATCH", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk", strings.NewReader(`{
"name": "string",
"type": "file",
"priceMinor": 0,
"compareAtMinor": 0,
"description": "string",
"delivers": "string",
"status": "active",
"lowStockThreshold": 0
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Delete a product (soft: orders keep it, it can be restored, its slug is freed)
/v1/store/products/{productId}Or name the store: DELETE /v1/stores/{storeId}/products/{productId}
Parameters
productIdprd_…pathrequired
Response Ok
okbooleanrequired
Example
curl -X DELETE "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"DELETE",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("DELETE", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Keys in the pool, with who each assigned key went to
/v1/store/products/{productId}/keysOr name the store: GET /v1/stores/{storeId}/products/{productId}/keys
Parameters
productIdprd_…pathrequiredstatus"available" | "assigned" | "all"queryvariantIdvar_… | nullqueryqstring | nullquerycursorstring | nullquerylimitinteger | stringquerysort"added" | "option" | "status" | "order"querydir"asc" | "desc"query
Response ListKeysResponse
itemsLicenseKeyRow[]requirednextCursorCursor | nullrequiredstatsKeyPoolStatsrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Add license keys or serials to a product pool (duplicates are skipped)
/v1/store/products/{productId}/keysOr name the store: POST /v1/stores/{storeId}/products/{productId}/keys
Parameters
productIdprd_…pathrequired
Body
keysstring[]required
Response AddLicenseKeysResponse
addedintegerrequiredskippedDuplicatesintegerrequiredstockintegerrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keys": [
"string"
]
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"keys": [
"string"
]
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"keys": [
"string"
]
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys", strings.NewReader(`{
"keys": [
"string"
]
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Pick the theme template a product page uses (null: the default product template)
/v1/store/products/{productId}/templateOr name the store: PUT /v1/stores/{storeId}/products/{productId}/template
Parameters
productIdprd_…pathrequired
Body
templateSuffixstring | nullrequired
Response SetProductTemplateResponse
productIdProductIdrequiredtemplateSuffixTemplateSuffix | nullrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/template" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateSuffix": "string"
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/template', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"templateSuffix": "string"
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/template",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"templateSuffix": "string"
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/template", strings.NewReader(`{
"templateSuffix": "string"
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Everything the product editor shows: variants, media, files, delivery, checkout fields, SEO and relations
/v1/store/products/{productId}/fullOr name the store: GET /v1/stores/{storeId}/products/{productId}/full
Parameters
productIdprd_…pathrequired
Response ProductFull
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
50 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequireddescriptionHtmlstringrequiredshortDescriptionstringrequiredfeaturedbooleanrequiredpwywMinMinorMinorUnits | nullrequiredpwywSuggestedMinorMinorUnits | nullrequiredtaxCategoryTaxCategoryrequiredtaxCategoryReviewTaxCategoryReviewminPerOrderintegerrequiredmaxPerOrderinteger | nullrequiredmaxPerCustomerinteger | nullrequiredstockModeStockModerequiredoutOfStockBehaviorOutOfStockBehaviorrequiredvariantsProductVariant[]requiredmediaProductMedia[]requiredfilesProductFile[]requiredkeyStatsKeyPoolStats | nullrequireddeliveryProductDeliveryrequiredcheckoutFieldsCheckoutField[]requiredseoProductSeorequiredpreviousSlugsstring[]requiredcollectionIdsCollectionId[]requiredcategoryIdsCategoryId[]requiredupsellIdsProductId[]requiredcrossSellIdsProductId[]requiredbundleProductIdsProductId[]requiredbundlePartsBundlePart[]requiredbundlePricingBundlePricingrequiredquantityTiersQuantityTier[]requiredtiersWithCouponsbooleanrequiredpaymentRulesPaymentRulesrequiredaffiliateCommissionBpsBps | nullrequiredfraudProductFraudrequiredtemplateSuffixstringrequireddeletedAtTimestamp | nullrequiredattributesProductAttributesrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Save the whole editor document. 409 when someone else saved since baseUpdatedAt
/v1/store/products/{productId}/fullOr name the store: PUT /v1/stores/{storeId}/products/{productId}/full
Parameters
productIdprd_…pathrequired
Body
productobjectrequirednamestringrequiredslugstring | nullrequiredtype"file" | "license_key" | "serial" | "subscription" | "discord_role" | "service" | "bundle"requiredstatus"active" | "draft" | "archived"requireddescriptionstringrequiredshortDescriptionstringrequireddeliversstringrequiredtagsstring[]requiredvisibility"public" | "unlisted" | "private"requiredpublishAtstring | nullrequiredfeaturedbooleanrequiredpricingMode"fixed" | "pay_what_you_want" | "free"requiredpriceMinorintegerrequiredcompareAtMinorinteger | nullrequiredpwywMinMinorinteger | nullrequiredpwywSuggestedMinorinteger | nullrequiredtaxCategory"digital_goods" | "ebook" | "software" | "saas" | "online_course" | "membership" | "service" | "exempt"requiredminPerOrderintegerrequiredmaxPerOrderinteger | nullrequiredmaxPerCustomerinteger | nullrequiredstockMode"unlimited" | "limited" | "key_pool" | "serial_pool"requiredstockinteger | nullrequiredlowStockThresholdintegerrequiredoutOfStockBehavior"hide" | "show_sold_out" | "allow_preorder"requiredvariantsobject[]requiredidvar_… | nullrequirednamestringrequireddescriptionstringrequiredpriceMinorintegerrequiredcompareAtMinorinteger | nullrequiredenabledbooleanrequiredstockinteger | nullrequireddeliveryNotestringrequiredfileRefsstring[]requireddiscordRoleIdstring | nullrequiredpaymentRulesobject | nulllowStockThresholdinteger | nullnewKeysstring[]
mediaobject[]requiredsourceobjectrequiredaltstringrequiredkind"image" | "video" | "youtube" | "vimeo"posterUrlstring | nullexternalIdstring | null
filesobject[]requiredidfil_… | nullrequiredrefstringrequirednamestringrequirednewVersionobject | nullrequired
deliveryobjectrequiredfileobjectrequiredkeysobjectrequireddiscordobjectrequiredsubscriptionobjectrequiredserviceobjectrequiredpostPurchaseMessagestringrequiredredirectUrlstring | nullrequireddynamicobjectwarrantyobject
checkoutFieldsobject[]requiredidstringrequiredlabelstringrequiredtype"text" | "textarea" | "email" | "number" | "select" | "checkbox" | "url" | "password" | "hidden" | "discord_id"requiredrequiredbooleanrequiredplaceholderstringrequiredhelpTextstringrequiredoptionsstring[]requireddefaultValuestring
seoobjectrequiredtitlestring | nullrequireddescriptionstring | nullrequiredogImage"cover" | "custom"requiredogImageUrlstring | nullrequired
collectionIdscol_…[]requiredcategoryIdspcat_…[]upsellIdsprd_…[]requiredcrossSellIdsprd_…[]requiredbundleProductIdsprd_…[]requiredbundlePartsobject[]productIdprd_…requiredvariantIdvar_… | nullrequired
bundlePricingobjectquantityTiersobject[]minQuantityintegerrequireddiscountBpsintegerrequired
tiersWithCouponsbooleanpaymentRulesobjectdisabledMethods"card" | "apple_pay" | "google_pay" | "paypal" | "crypto" | "bank_transfer" | "store_credit" | "manual" | "cash_app" | "skins" | "gift_code"[]requiredmultipliersobject[]required
affiliateCommissionBpsinteger | nullrequiredfraudobjectrequiredblockVpnbooleanrequiredrequireVerifiedEmailbooleanrequired
newKeysstring[]attributesobjectgamestring | nullplatforms"windows" | "mac" | "linux" | "steam" | "epic" | "battlenet" | "riot" | "ea" | "ubisoft" | "xbox" | "playstation" | "switch" | "android" | "ios" | "web" | "other"[]regionstring | nullstatus"undetected" | "updated" | "testing" | "updating" | "detected" | "down" | nullstatusNotestringstatusUpdatedAtstring | nullinstantDeliverybooleanpresetKeystring | nullfeaturesstring[]featureGroupsobject[]requirementsstring[]
baseUpdatedAtstring | nullrequired
Response ProductSaved
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
51 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequireddescriptionHtmlstringrequiredshortDescriptionstringrequiredfeaturedbooleanrequiredpwywMinMinorMinorUnits | nullrequiredpwywSuggestedMinorMinorUnits | nullrequiredtaxCategoryTaxCategoryrequiredtaxCategoryReviewTaxCategoryReviewminPerOrderintegerrequiredmaxPerOrderinteger | nullrequiredmaxPerCustomerinteger | nullrequiredstockModeStockModerequiredoutOfStockBehaviorOutOfStockBehaviorrequiredvariantsProductVariant[]requiredmediaProductMedia[]requiredfilesProductFile[]requiredkeyStatsKeyPoolStats | nullrequireddeliveryProductDeliveryrequiredcheckoutFieldsCheckoutField[]requiredseoProductSeorequiredpreviousSlugsstring[]requiredcollectionIdsCollectionId[]requiredcategoryIdsCategoryId[]requiredupsellIdsProductId[]requiredcrossSellIdsProductId[]requiredbundleProductIdsProductId[]requiredbundlePartsBundlePart[]requiredbundlePricingBundlePricingrequiredquantityTiersQuantityTier[]requiredtiersWithCouponsbooleanrequiredpaymentRulesPaymentRulesrequiredaffiliateCommissionBpsBps | nullrequiredfraudProductFraudrequiredtemplateSuffixstringrequireddeletedAtTimestamp | nullrequiredattributesProductAttributesrequiredkeyImportobjectrequiredaddedintegerrequiredalreadyInPoolintegerrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product": {
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": false,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": false,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": false
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": false,
"removeOnExpiry": false
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": false,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": false,
"requireVerifiedEmail": false
}
},
"baseUpdatedAt": "2026-10-21T12:00:00.000Z"
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"product": {
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": false,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": false,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": false
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": false,
"removeOnExpiry": false
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": false,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": false,
"requireVerifiedEmail": false
}
},
"baseUpdatedAt": "2026-10-21T12:00:00.000Z"
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"product": {
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": False,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": False,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": False
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": False,
"removeOnExpiry": False
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": False,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": False,
"requireVerifiedEmail": False
}
},
"baseUpdatedAt": "2026-10-21T12:00:00.000Z"
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/full", strings.NewReader(`{
"product": {
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": false,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": false,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": false
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": false,
"removeOnExpiry": false
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": false,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": false,
"requireVerifiedEmail": false
}
},
"baseUpdatedAt": "2026-10-21T12:00:00.000Z"
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Create a product from the editor (description sanitized, slug unique per store)
/v1/store/products/fullOr name the store: POST /v1/stores/{storeId}/products/full
Body
namestringrequiredslugstring | nullrequiredtype"file" | "license_key" | "serial" | "subscription" | "discord_role" | "service" | "bundle"requiredstatus"active" | "draft" | "archived"requireddescriptionstringrequiredshortDescriptionstringrequireddeliversstringrequiredtagsstring[]requiredvisibility"public" | "unlisted" | "private"requiredpublishAtstring | nullrequiredfeaturedbooleanrequiredpricingMode"fixed" | "pay_what_you_want" | "free"requiredpriceMinorintegerrequiredcompareAtMinorinteger | nullrequiredpwywMinMinorinteger | nullrequiredpwywSuggestedMinorinteger | nullrequiredtaxCategory"digital_goods" | "ebook" | "software" | "saas" | "online_course" | "membership" | "service" | "exempt"requiredminPerOrderintegerrequiredmaxPerOrderinteger | nullrequiredmaxPerCustomerinteger | nullrequiredstockMode"unlimited" | "limited" | "key_pool" | "serial_pool"requiredstockinteger | nullrequiredlowStockThresholdintegerrequiredoutOfStockBehavior"hide" | "show_sold_out" | "allow_preorder"requiredvariantsobject[]requiredidvar_… | nullrequirednamestringrequireddescriptionstringrequiredpriceMinorintegerrequiredcompareAtMinorinteger | nullrequiredenabledbooleanrequiredstockinteger | nullrequireddeliveryNotestringrequiredfileRefsstring[]requireddiscordRoleIdstring | nullrequiredpaymentRulesobject | nulllowStockThresholdinteger | nullnewKeysstring[]
mediaobject[]requiredsourceobjectrequiredaltstringrequiredkind"image" | "video" | "youtube" | "vimeo"posterUrlstring | nullexternalIdstring | null
filesobject[]requiredidfil_… | nullrequiredrefstringrequirednamestringrequirednewVersionobject | nullrequired
deliveryobjectrequiredfileobjectrequireddownloadLimitinteger | nullrequiredlinkExpiryHoursinteger | nullrequirednotifyOnUpdatebooleanrequired
keysobjectrequiredpatternstring | nullrequiredinstructionsstringrequired
discordobjectrequiredguildIdstring | nullrequiredroleIdstring | nullrequiredroleNamestringrequiredremoveOnRefundbooleanrequiredremoveOnExpirybooleanrequiredmode"disabled" | "optional" | "mandatory"extraGrantsobject[]
subscriptionobjectrequiredinterval"week" | "month" | "year"requiredintervalCountintegerrequiredtrialDaysintegerrequiredrenewalReminderDaysintegerrequiredcancelBehavior"end_of_period" | "immediately"requiredgracePeriodDaysintegerrequired
serviceobjectrequiredinstructionsstringrequiredbookingUrlstring | nullrequiredturnaroundDaysinteger | nullrequired
postPurchaseMessagestringrequiredredirectUrlstring | nullrequireddynamicobjectenabledbooleanrequiredurlstring | nullrequiredsecretVersionintegerrequired
warrantyobjectdaysinteger | nullrequiredtermsstringrequired
checkoutFieldsobject[]requiredidstringrequiredlabelstringrequiredtype"text" | "textarea" | "email" | "number" | "select" | "checkbox" | "url" | "password" | "hidden" | "discord_id"requiredrequiredbooleanrequiredplaceholderstringrequiredhelpTextstringrequiredoptionsstring[]requireddefaultValuestring
seoobjectrequiredtitlestring | nullrequireddescriptionstring | nullrequiredogImage"cover" | "custom"requiredogImageUrlstring | nullrequired
collectionIdscol_…[]requiredcategoryIdspcat_…[]upsellIdsprd_…[]requiredcrossSellIdsprd_…[]requiredbundleProductIdsprd_…[]requiredbundlePartsobject[]productIdprd_…requiredvariantIdvar_… | nullrequired
bundlePricingobjectquantityTiersobject[]minQuantityintegerrequireddiscountBpsintegerrequired
tiersWithCouponsbooleanpaymentRulesobjectdisabledMethods"card" | "apple_pay" | "google_pay" | "paypal" | "crypto" | "bank_transfer" | "store_credit" | "manual" | "cash_app" | "skins" | "gift_code"[]requiredmultipliersobject[]requiredmethod"card" | "apple_pay" | "google_pay" | "paypal" | "crypto" | "bank_transfer" | "store_credit" | "manual" | "cash_app" | "skins" | "gift_code"requiredbpsintegerrequired
affiliateCommissionBpsinteger | nullrequiredfraudobjectrequiredblockVpnbooleanrequiredrequireVerifiedEmailbooleanrequired
newKeysstring[]attributesobjectgamestring | nullplatforms"windows" | "mac" | "linux" | "steam" | "epic" | "battlenet" | "riot" | "ea" | "ubisoft" | "xbox" | "playstation" | "switch" | "android" | "ios" | "web" | "other"[]regionstring | nullstatus"undetected" | "updated" | "testing" | "updating" | "detected" | "down" | nullstatusNotestringstatusUpdatedAtstring | nullinstantDeliverybooleanpresetKeystring | nullfeaturesstring[]featureGroupsobject[]titlestringrequireditemsstring[]required
requirementsstring[]
Response ProductSaved
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
51 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequireddescriptionHtmlstringrequiredshortDescriptionstringrequiredfeaturedbooleanrequiredpwywMinMinorMinorUnits | nullrequiredpwywSuggestedMinorMinorUnits | nullrequiredtaxCategoryTaxCategoryrequiredtaxCategoryReviewTaxCategoryReviewminPerOrderintegerrequiredmaxPerOrderinteger | nullrequiredmaxPerCustomerinteger | nullrequiredstockModeStockModerequiredoutOfStockBehaviorOutOfStockBehaviorrequiredvariantsProductVariant[]requiredmediaProductMedia[]requiredfilesProductFile[]requiredkeyStatsKeyPoolStats | nullrequireddeliveryProductDeliveryrequiredcheckoutFieldsCheckoutField[]requiredseoProductSeorequiredpreviousSlugsstring[]requiredcollectionIdsCollectionId[]requiredcategoryIdsCategoryId[]requiredupsellIdsProductId[]requiredcrossSellIdsProductId[]requiredbundleProductIdsProductId[]requiredbundlePartsBundlePart[]requiredbundlePricingBundlePricingrequiredquantityTiersQuantityTier[]requiredtiersWithCouponsbooleanrequiredpaymentRulesPaymentRulesrequiredaffiliateCommissionBpsBps | nullrequiredfraudProductFraudrequiredtemplateSuffixstringrequireddeletedAtTimestamp | nullrequiredattributesProductAttributesrequiredkeyImportobjectrequiredaddedintegerrequiredalreadyInPoolintegerrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/full" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": false,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": false,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": false
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": false,
"removeOnExpiry": false
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": false,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"categoryIds": [
"pcat_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"bundleParts": [],
"bundlePricing": {
"kind": "fixed"
},
"quantityTiers": [],
"tiersWithCoupons": true,
"paymentRules": {
"disabledMethods": [],
"multipliers": []
},
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": false,
"requireVerifiedEmail": false
},
"newKeys": [],
"attributes": {}
}'const res = await fetch('https://api.shopfa.st/v1/store/products/full', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": false,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": false,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": false
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": false,
"removeOnExpiry": false
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": false,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"categoryIds": [
"pcat_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"bundleParts": [],
"bundlePricing": {
"kind": "fixed"
},
"quantityTiers": [],
"tiersWithCoupons": true,
"paymentRules": {
"disabledMethods": [],
"multipliers": []
},
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": false,
"requireVerifiedEmail": false
},
"newKeys": [],
"attributes": {}
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/full",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": False,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": False,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": False
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": False,
"removeOnExpiry": False
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": False,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"categoryIds": [
"pcat_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"bundleParts": [],
"bundlePricing": {
"kind": "fixed"
},
"quantityTiers": [],
"tiersWithCoupons": True,
"paymentRules": {
"disabledMethods": [],
"multipliers": []
},
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": False,
"requireVerifiedEmail": False
},
"newKeys": [],
"attributes": {}
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/full", strings.NewReader(`{
"name": "string",
"slug": "string",
"type": "file",
"status": "active",
"description": "string",
"shortDescription": "string",
"delivers": "string",
"tags": [
"string"
],
"visibility": "public",
"publishAt": "2026-10-21T12:00:00.000Z",
"featured": false,
"pricingMode": "fixed",
"priceMinor": 0,
"compareAtMinor": 0,
"pwywMinMinor": 0,
"pwywSuggestedMinor": 0,
"taxCategory": "digital_goods",
"minPerOrder": 1,
"maxPerOrder": 1,
"maxPerCustomer": 1,
"stockMode": "unlimited",
"stock": 0,
"lowStockThreshold": 0,
"outOfStockBehavior": "hide",
"variants": [
{
"id": "var_0123456789abcdefghjk",
"name": "string",
"description": "string",
"priceMinor": 0,
"compareAtMinor": 0,
"enabled": false,
"stock": 0,
"deliveryNote": "string",
"fileRefs": [
"string"
],
"discordRoleId": "string"
}
],
"media": [
{
"source": {
"mediaId": "med_0123456789abcdefghjk"
},
"alt": "string"
}
],
"files": [
{
"id": "fil_0123456789abcdefghjk",
"ref": "string",
"name": "string",
"newVersion": {
"uploadId": "upl_0123456789abcdefghjk",
"version": "string",
"changelog": "string"
}
}
],
"delivery": {
"file": {
"downloadLimit": 1,
"linkExpiryHours": 1,
"notifyOnUpdate": false
},
"keys": {
"pattern": "string",
"instructions": "string"
},
"discord": {
"guildId": "string",
"roleId": "string",
"roleName": "string",
"removeOnRefund": false,
"removeOnExpiry": false
},
"subscription": {
"interval": "week",
"intervalCount": 1,
"trialDays": 0,
"renewalReminderDays": 0,
"cancelBehavior": "end_of_period",
"gracePeriodDays": 0
},
"service": {
"instructions": "string",
"bookingUrl": "https://example.com",
"turnaroundDays": 1
},
"postPurchaseMessage": "string",
"redirectUrl": "https://example.com"
},
"checkoutFields": [
{
"id": "string",
"label": "string",
"type": "text",
"required": false,
"placeholder": "string",
"helpText": "string",
"options": [
"string"
]
}
],
"seo": {
"title": "string",
"description": "string",
"ogImage": "cover",
"ogImageUrl": "string"
},
"collectionIds": [
"col_0123456789abcdefghjk"
],
"categoryIds": [
"pcat_0123456789abcdefghjk"
],
"upsellIds": [
"prd_0123456789abcdefghjk"
],
"crossSellIds": [
"prd_0123456789abcdefghjk"
],
"bundleProductIds": [
"prd_0123456789abcdefghjk"
],
"bundleParts": [],
"bundlePricing": {
"kind": "fixed"
},
"quantityTiers": [],
"tiersWithCoupons": true,
"paymentRules": {
"disabledMethods": [],
"multipliers": []
},
"affiliateCommissionBps": 0,
"fraud": {
"blockVpn": false,
"requireVerifiedEmail": false
},
"newKeys": [],
"attributes": {}
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Who last changed a product and when, and how many sales changed its stock since a time (the editor explains a save conflict with it)
/v1/store/products/{productId}/last-editOr name the store: GET /v1/stores/{storeId}/products/{productId}/last-edit
Parameters
productIdprd_…pathrequiredsincestring | nullquery
Response ProductLastEdit
updatedAtTimestamprequirededitedByobject | nullrequirededitedAtTimestamp | nullrequiredsalesSinceintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/last-edit" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/last-edit', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/last-edit",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/last-edit", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Copy a product as a draft (variants, media, files, settings; not keys or sales)
/v1/store/products/{productId}/duplicateOr name the store: POST /v1/stores/{storeId}/products/{productId}/duplicate
Parameters
productIdprd_…pathrequired
Response ProductFull
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
50 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequireddescriptionHtmlstringrequiredshortDescriptionstringrequiredfeaturedbooleanrequiredpwywMinMinorMinorUnits | nullrequiredpwywSuggestedMinorMinorUnits | nullrequiredtaxCategoryTaxCategoryrequiredtaxCategoryReviewTaxCategoryReviewminPerOrderintegerrequiredmaxPerOrderinteger | nullrequiredmaxPerCustomerinteger | nullrequiredstockModeStockModerequiredoutOfStockBehaviorOutOfStockBehaviorrequiredvariantsProductVariant[]requiredmediaProductMedia[]requiredfilesProductFile[]requiredkeyStatsKeyPoolStats | nullrequireddeliveryProductDeliveryrequiredcheckoutFieldsCheckoutField[]requiredseoProductSeorequiredpreviousSlugsstring[]requiredcollectionIdsCollectionId[]requiredcategoryIdsCategoryId[]requiredupsellIdsProductId[]requiredcrossSellIdsProductId[]requiredbundleProductIdsProductId[]requiredbundlePartsBundlePart[]requiredbundlePricingBundlePricingrequiredquantityTiersQuantityTier[]requiredtiersWithCouponsbooleanrequiredpaymentRulesPaymentRulesrequiredaffiliateCommissionBpsBps | nullrequiredfraudProductFraudrequiredtemplateSuffixstringrequireddeletedAtTimestamp | nullrequiredattributesProductAttributesrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/duplicate" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/duplicate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/duplicate",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/duplicate", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Restore a deleted product as a draft
/v1/store/products/{productId}/restoreOr name the store: POST /v1/stores/{storeId}/products/{productId}/restore
Parameters
productIdprd_…pathrequired
Response ProductFull
idProductIdrequiredstoreIdStoreIdrequirednamestringrequiredslugstringrequiredtypeProductTyperequiredstatusProductStatusrequiredpriceMinorMinorUnitsrequiredcompareAtMinorMinorUnits | nullrequiredcurrencyCurrencyCoderequireddescriptionstringrequired
50 more fields
deliversstringrequiredcoverUrlstringrequiredstockinteger | nullrequiredlowStockThresholdintegerrequiredunitsSoldintegerrequiredrevenueMinorMinorUnitsrequiredcreatedAtTimestamprequiredupdatedAtTimestamprequiredvisibilityProductVisibilityrequiredpricingModePricingModerequiredvariantCountintegerrequiredpriceMaxMinorMinorUnits | nullrequiredtagsstring[]requiredpublishAtTimestamp | nullrequiredplanLockedAtTimestamp | nullrequireddescriptionHtmlstringrequiredshortDescriptionstringrequiredfeaturedbooleanrequiredpwywMinMinorMinorUnits | nullrequiredpwywSuggestedMinorMinorUnits | nullrequiredtaxCategoryTaxCategoryrequiredtaxCategoryReviewTaxCategoryReviewminPerOrderintegerrequiredmaxPerOrderinteger | nullrequiredmaxPerCustomerinteger | nullrequiredstockModeStockModerequiredoutOfStockBehaviorOutOfStockBehaviorrequiredvariantsProductVariant[]requiredmediaProductMedia[]requiredfilesProductFile[]requiredkeyStatsKeyPoolStats | nullrequireddeliveryProductDeliveryrequiredcheckoutFieldsCheckoutField[]requiredseoProductSeorequiredpreviousSlugsstring[]requiredcollectionIdsCollectionId[]requiredcategoryIdsCategoryId[]requiredupsellIdsProductId[]requiredcrossSellIdsProductId[]requiredbundleProductIdsProductId[]requiredbundlePartsBundlePart[]requiredbundlePricingBundlePricingrequiredquantityTiersQuantityTier[]requiredtiersWithCouponsbooleanrequiredpaymentRulesPaymentRulesrequiredaffiliateCommissionBpsBps | nullrequiredfraudProductFraudrequiredtemplateSuffixstringrequireddeletedAtTimestamp | nullrequiredattributesProductAttributesrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/restore" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/restore', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/restore",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/restore", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Apply one action to many products
/v1/store/products/bulkOr name the store: POST /v1/stores/{storeId}/products/bulk
Body
productIdsprd_…[]requiredopobjectrequired
Response BulkProductsResponse
updatedintegerrequiredcreatedProductId[]requiredskippedobject[]requiredproductIdProductIdrequiredreasonstringrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/bulk" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"productIds": [
"prd_0123456789abcdefghjk"
],
"op": {
"action": "set_status",
"status": "active"
}
}'const res = await fetch('https://api.shopfa.st/v1/store/products/bulk', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"productIds": [
"prd_0123456789abcdefghjk"
],
"op": {
"action": "set_status",
"status": "active"
}
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/bulk",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"productIds": [
"prd_0123456789abcdefghjk"
],
"op": {
"action": "set_status",
"status": "active"
}
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/bulk", strings.NewReader(`{
"productIds": [
"prd_0123456789abcdefghjk"
],
"op": {
"action": "set_status",
"status": "active"
}
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Every product as CSV (PRODUCT_CSV_COLUMNS)
/v1/store/products/exportOr name the store: GET /v1/stores/{storeId}/products/export
Response ExportProductsResponse
filenamestringrequiredcsvstringrequired
Example
curl "https://api.shopfa.st/v1/store/products/export" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/export', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/export",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/export", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Create or update products from CSV (matched by slug). dryRun validates without writing; any error writes nothing
/v1/store/products/importOr name the store: POST /v1/stores/{storeId}/products/import
Body
csvstringrequireddryRunbooleanrequired
Response ProductImportResult
createdintegerrequiredupdatedintegerrequiredskippedintegerrequiredcategoriesCreatedintegerrequiredrowsProductImportRow[]requirederrorsobject[]requiredlineintegerrequiredcolumnstringrequiredmessagestringrequired
dryRunbooleanrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/import" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"csv": "string",
"dryRun": false
}'const res = await fetch('https://api.shopfa.st/v1/store/products/import', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"csv": "string",
"dryRun": false
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/import",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"csv": "string",
"dryRun": False
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/import", strings.NewReader(`{
"csv": "string",
"dryRun": false
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Recently deleted products that can be restored
/v1/store/products/deletedOr name the store: GET /v1/stores/{storeId}/products/deleted
Response ListDeletedProductsResponse
itemsobject[]requiredidProductIdrequirednamestringrequiredtypestringrequireddeletedAtTimestamprequired
Example
curl "https://api.shopfa.st/v1/store/products/deleted" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/deleted', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/deleted",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/deleted", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
The signing secret for this product's delivery URL (Standard Webhooks)
/v1/store/products/{productId}/delivery-webhook/secretOr name the store: GET /v1/stores/{storeId}/products/{productId}/delivery-webhook/secret
Parameters
productIdprd_…pathrequired
Response DeliveryWebhookSecret
secretstringrequiredversionintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/secret" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/secret', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/secret",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/secret", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Replace the signing secret; the old one stops verifying at once
/v1/store/products/{productId}/delivery-webhook/rotateOr name the store: POST /v1/stores/{storeId}/products/{productId}/delivery-webhook/rotate
Parameters
productIdprd_…pathrequired
Response DeliveryWebhookSecret
secretstringrequiredversionintegerrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/rotate" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/rotate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/rotate",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/rotate", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Call a delivery URL with a signed sample order and show what buyers would get
/v1/store/products/{productId}/delivery-webhook/testOr name the store: POST /v1/stores/{storeId}/products/{productId}/delivery-webhook/test
Parameters
productIdprd_…pathrequired
Body
urlstringrequired
Response DeliveryWebhookTest
okbooleanrequiredstatusinteger | nullrequireddurationMsintegerrequirederrorstringrequiredkeysstring[]requiredmessagestringrequiredbodyPreviewstringrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/test" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com"
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/test', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"url": "https://example.com"
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/test",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"url": "https://example.com"
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/delivery-webhook/test", strings.NewReader(`{
"url": "https://example.com"
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Subscriptions to this product: state, period end and renewals
/v1/store/products/{productId}/subscribersOr name the store: GET /v1/stores/{storeId}/products/{productId}/subscribers
Parameters
productIdprd_…pathrequiredstate"all" | "active" | "past_due" | "ended"query
Response ListProductSubscribersResponse
itemsProductSubscriber[]requiredcountsobjectrequiredactiveintegerrequiredpastDueintegerrequiredendedintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Cancel a subscription now (access ends and Discord roles come off) or at the period end
/v1/store/products/{productId}/subscribers/{subscriptionId}/cancelOr name the store: POST /v1/stores/{storeId}/products/{productId}/subscribers/{subscriptionId}/cancel
Parameters
productIdprd_…pathrequiredsubscriptionIdsub_…pathrequired
Body
when"now" | "period_end"required
Response ProductSubscriber
idSubscriptionIdrequiredemailstringrequiredstateSubscriberStaterequiredorderIdOrderIdrequiredorderNumberstringrequiredcurrentPeriodEndTimestamprequiredrenewalsintegerrequiredcreatedAtTimestamprequiredendedAtTimestamp | nullrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers/sub_0123456789abcdefghjk/cancel" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"when": "now"
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers/sub_0123456789abcdefghjk/cancel', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"when": "now"
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers/sub_0123456789abcdefghjk/cancel",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"when": "now"
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/subscribers/sub_0123456789abcdefghjk/cancel", strings.NewReader(`{
"when": "now"
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
A short-lived link for the seller to download the current version of a deliverable
/v1/store/products/{productId}/files/{fileId}/downloadOr name the store: GET /v1/stores/{storeId}/products/{productId}/files/{fileId}/download
Parameters
productIdprd_…pathrequiredfileIdfil_…pathrequired
Response GetFileDownloadUrlResponse
urlstringrequiredexpiresAtTimestamprequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/files/fil_0123456789abcdefghjk/download" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/files/fil_0123456789abcdefghjk/download', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/files/fil_0123456789abcdefghjk/download",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/files/fil_0123456789abcdefghjk/download", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Import keys or serials from pasted text or CSV: format check, duplicates skipped, optionally reserved for one option
/v1/store/products/{productId}/keys/importOr name the store: POST /v1/stores/{storeId}/products/{productId}/keys/import
Parameters
productIdprd_…pathrequired
Body
textstringrequireddelimiter"newline" | "comma" | "semicolon" | "tab" | "csv"requiredvariantIdvar_… | nullrequiredstrictbooleanrequired
Response KeyImportResult
addedintegerrequiredduplicatesInInputintegerrequiredduplicatesInPoolintegerrequiredinvalidobject[]requiredlineintegerrequiredvaluestringrequired
invalidCountintegerrequiredstockintegerrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/import" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "string",
"delimiter": "newline",
"variantId": "var_0123456789abcdefghjk",
"strict": false
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/import', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "string",
"delimiter": "newline",
"variantId": "var_0123456789abcdefghjk",
"strict": false
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/import",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"text": "string",
"delimiter": "newline",
"variantId": "var_0123456789abcdefghjk",
"strict": False
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/import", strings.NewReader(`{
"text": "string",
"delimiter": "newline",
"variantId": "var_0123456789abcdefghjk",
"strict": false
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Keys as CSV (value, status, option, order, assigned at)
/v1/store/products/{productId}/keys/exportOr name the store: GET /v1/stores/{storeId}/products/{productId}/keys/export
Parameters
productIdprd_…pathrequiredstatus"available" | "assigned" | "all"queryvariantIdvar_… | nullquery
Response ExportProductsResponse
filenamestringrequiredcsvstringrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/export" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/export', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/export",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/export", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Remove unused keys from the pool (assigned keys are never removed)
/v1/store/products/{productId}/keys/removeOr name the store: POST /v1/stores/{storeId}/products/{productId}/keys/remove
Parameters
productIdprd_…pathrequired
Body
keyIdskey_…[]required
Response RemoveKeysResponse
removedintegerrequiredstockintegerrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/remove" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keyIds": [
"key_0123456789abcdefghjk"
]
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/remove', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"keyIds": [
"key_0123456789abcdefghjk"
]
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/remove",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"keyIds": [
"key_0123456789abcdefghjk"
]
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/remove", strings.NewReader(`{
"keyIds": [
"key_0123456789abcdefghjk"
]
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Move a product in the order the storefront lists products (or in a hand-picked collection): first, last, or next to another product
/v1/store/products/{productId}/moveOr name the store: POST /v1/stores/{storeId}/products/{productId}/move
Parameters
productIdprd_…pathrequired
Body
to"top" | "bottom" | "before" | "after" | "position"requiredanchorprd_… | nullpositioninteger | nullcollectionIdcol_… | null
Response ProductMoved
productIdProductIdrequiredindexintegerrequiredtotalintegerrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/move" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "top",
"anchor": null,
"position": null,
"collectionId": null
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/move', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"to": "top",
"anchor": null,
"position": null,
"collectionId": null
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/move",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"to": "top",
"anchor": None,
"position": None,
"collectionId": None
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/move", strings.NewReader(`{
"to": "top",
"anchor": null,
"position": null,
"collectionId": null
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Show one license key in full
/v1/store/products/{productId}/keys/{keyId}/revealOr name the store: POST /v1/stores/{storeId}/products/{productId}/keys/{keyId}/reveal
Parameters
productIdprd_…pathrequiredkeyIdkey_…pathrequired
Response RevealLicenseKeyResponse
valuestringrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/key_0123456789abcdefghjk/reveal" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/key_0123456789abcdefghjk/reveal', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/key_0123456789abcdefghjk/reveal",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/keys/key_0123456789abcdefghjk/reveal", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
A product’s licensing: API keys, device binding, expiry clock, auto-pause and linked status
/v1/store/products/{productId}/licensingOr name the store: GET /v1/stores/{storeId}/products/{productId}/licensing
Parameters
productIdprd_…pathrequired
Response ProductLicensing
productIdProductIdrequiredsettingsLicenseSettingsrequiredpublishableKeyPublishableLicenseKey | nullrequiredpublicKeystringrequiredpublicKeyIdstringrequiredkeysRotatedAtTimestamp | nullrequiredplansLicensePlanOut[]requiredlinkedComponentsLinkedComponent[]requiredpausedNowSalesPause | nullrequiredrecentPausesSalesPause[]requiredstatsobjectrequiredactiveintegerrequiredexpiredintegerrequirednotStartedintegerrequiredrevokedintegerrequireddevicesintegerrequiredvalidations24hintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Save a product’s licensing settings (turning the API on mints its keys)
/v1/store/products/{productId}/licensingOr name the store: PUT /v1/stores/{storeId}/products/{productId}/licensing
Parameters
productIdprd_…pathrequired
Body
apiEnabledbooleanclock"purchase" | "activation"hwidobjectenabledbooleanmaxDevicesintegerbuyerResetsPer30dintegerresetCooldownHoursinteger
autoPauseobjectenabledbooleanwhen"outage" | "degraded" | "not_live"storefront"show_disabled" | "hide"blockValidationbooleancompensatebooleannotifyBuyersboolean
extendEnabledbooleanmetadataobjectrateLimitPerMinuteinteger
Response ProductLicensing
productIdProductIdrequiredsettingsLicenseSettingsrequiredpublishableKeyPublishableLicenseKey | nullrequiredpublicKeystringrequiredpublicKeyIdstringrequiredkeysRotatedAtTimestamp | nullrequiredplansLicensePlanOut[]requiredlinkedComponentsLinkedComponent[]requiredpausedNowSalesPause | nullrequiredrecentPausesSalesPause[]requiredstatsobjectrequiredactiveintegerrequiredexpiredintegerrequirednotStartedintegerrequiredrevokedintegerrequireddevicesintegerrequiredvalidations24hintegerrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"apiEnabled": false,
"clock": "purchase",
"hwid": {},
"autoPause": {},
"extendEnabled": true,
"metadata": {},
"rateLimitPerMinute": 60
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"apiEnabled": false,
"clock": "purchase",
"hwid": {},
"autoPause": {},
"extendEnabled": true,
"metadata": {},
"rateLimitPerMinute": 60
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"apiEnabled": False,
"clock": "purchase",
"hwid": {},
"autoPause": {},
"extendEnabled": True,
"metadata": {},
"rateLimitPerMinute": 60
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing", strings.NewReader(`{
"apiEnabled": false,
"clock": "purchase",
"hwid": {},
"autoPause": {},
"extendEnabled": true,
"metadata": {},
"rateLimitPerMinute": 60
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Replace the product’s publishable key or its signing key (old ones stop working at once)
/v1/store/products/{productId}/licensing/rotateOr name the store: POST /v1/stores/{storeId}/products/{productId}/licensing/rotate
Parameters
productIdprd_…pathrequired
Body
which"publishable" | "signing"required
Response ProductLicensing
productIdProductIdrequiredsettingsLicenseSettingsrequiredpublishableKeyPublishableLicenseKey | nullrequiredpublicKeystringrequiredpublicKeyIdstringrequiredkeysRotatedAtTimestamp | nullrequiredplansLicensePlanOut[]requiredlinkedComponentsLinkedComponent[]requiredpausedNowSalesPause | nullrequiredrecentPausesSalesPause[]requiredstatsobjectrequiredactiveintegerrequiredexpiredintegerrequirednotStartedintegerrequiredrevokedintegerrequireddevicesintegerrequiredvalidations24hintegerrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing/rotate" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"which": "publishable"
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing/rotate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"which": "publishable"
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing/rotate",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"which": "publishable"
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/licensing/rotate", strings.NewReader(`{
"which": "publishable"
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
A product’s self-serve replacement policy (window, limit, reason and proof, automatic or reviewed) and its queue numbers
/v1/store/products/{productId}/replacement-policyOr name the store: GET /v1/stores/{storeId}/products/{productId}/replacement-policy
Parameters
productIdprd_…pathrequired
Response ProductReplacementPolicy
productIdProductIdrequiredpolicyReplacementPolicyrequiredwarrantyDaysinteger | nullrequiredstatsobjectrequiredpendingintegerrequiredapproved30dintegerrequiredrejected30dintegerrequiredpoolAvailableintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Save a product’s self-serve replacement policy
/v1/store/products/{productId}/replacement-policyOr name the store: PUT /v1/stores/{storeId}/products/{productId}/replacement-policy
Parameters
productIdprd_…pathrequired
Body
enabledbooleanwindowDaysinteger | nullmaxReplacementsintegerrequireReasonbooleanrequireProofTextbooleanrequireProofUploadbooleanapproval"auto" | "review"
Response ProductReplacementPolicy
productIdProductIdrequiredpolicyReplacementPolicyrequiredwarrantyDaysinteger | nullrequiredstatsobjectrequiredpendingintegerrequiredapproved30dintegerrequiredrejected30dintegerrequiredpoolAvailableintegerrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": false,
"windowDays": null,
"maxReplacements": 1,
"requireReason": true,
"requireProofText": false,
"requireProofUpload": false,
"approval": "review"
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": false,
"windowDays": null,
"maxReplacements": 1,
"requireReason": true,
"requireProofText": false,
"requireProofUpload": false,
"approval": "review"
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"enabled": False,
"windowDays": None,
"maxReplacements": 1,
"requireReason": True,
"requireProofText": False,
"requireProofUpload": False,
"approval": "review"
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/replacement-policy", strings.NewReader(`{
"enabled": false,
"windowDays": null,
"maxReplacements": 1,
"requireReason": true,
"requireProofText": false,
"requireProofUpload": false,
"approval": "review"
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Who owns the product and who each channel would reach with these filters (consent applied)
/v1/store/products/{productId}/broadcasts/audienceOr name the store: POST /v1/stores/{storeId}/products/{productId}/broadcasts/audience
Parameters
productIdprd_…pathrequired
Body
activeOnlybooleanvariantIdsvar_…[]purchasedAfterstring | nullpurchasedBeforestring | nullmarketingOnlyboolean
Response BroadcastAudience
ownersintegerrequiredemailobjectrequiredeligibleintegerrequiredskippedobject[]requiredreasonBroadcastSkipReasonrequiredcountintegerrequired
discordintegerrequiredtelegramintegerrequiredsampleobject[]requiredemailstringrequiredoptionstringrequiredpurchasedAtTimestamprequiredactivebooleanrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/audience" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"activeOnly": true,
"variantIds": [],
"purchasedAfter": null,
"purchasedBefore": null,
"marketingOnly": false
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/audience', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"activeOnly": true,
"variantIds": [],
"purchasedAfter": null,
"purchasedBefore": null,
"marketingOnly": false
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/audience",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"activeOnly": True,
"variantIds": [],
"purchasedAfter": None,
"purchasedBefore": None,
"marketingOnly": False
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/audience", strings.NewReader(`{
"activeOnly": true,
"variantIds": [],
"purchasedAfter": null,
"purchasedBefore": null,
"marketingOnly": false
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Post an update to owners: adds the version to the history, attaches the new file version and sends in the background
/v1/store/products/{productId}/broadcastsOr name the store: POST /v1/stores/{storeId}/products/{productId}/broadcasts
Parameters
productIdprd_…pathrequired
Body
titlestringrequiredversionstringchangelogstringchannelsobjectrequiredemailbooleanrequireddiscordbooleanrequiredtelegrambooleanrequired
docobjectrequiredversionnumbersubjectstringrequiredpreheaderstringstyleobjectaccentstring | nullbackgroundstringsurfacestringtextstringmutedstringborderstringbuttonTextstringradiusintegerbuttonRadiusintegerfont"system" | "humanist" | "geometric" | "serif" | "mono"widthintegershowLogobooleanaccentBarboolean
blocksobject[]required
dmTextstringfiltersobjectrequiredactiveOnlybooleanvariantIdsvar_…[]purchasedAfterstring | nullpurchasedBeforestring | nullmarketingOnlyboolean
fileobject | nullshowInLibraryboolean
Response ProductBroadcast
idProductBroadcastIdrequiredproductIdProductIdrequiredproductNamestringrequiredtitlestringrequiredversionstringrequiredchangelogstringrequiredchannelsBroadcastChannelsrequiredfiltersBroadcastFiltersrequiredstatusBroadcastStatusrequiredcountsBroadcastCountsrequired
5 more fields
fileobject | nullrequiredshowInLibrarybooleanrequiredcreatedBystringrequiredcreatedAtTimestamprequiredfinishedAtTimestamp | nullrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": False,
"discord": False,
"telegram": False
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": None,
"showInLibrary": True
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts", strings.NewReader(`{
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Send the update email to yourself with sample values
/v1/store/products/{productId}/broadcasts/testOr name the store: POST /v1/stores/{storeId}/products/{productId}/broadcasts/test
Parameters
productIdprd_…pathrequired
Body
titlestringrequiredversionstringchangelogstringchannelsobjectrequiredemailbooleanrequireddiscordbooleanrequiredtelegrambooleanrequired
docobjectrequiredversionnumbersubjectstringrequiredpreheaderstringstyleobjectaccentstring | nullbackgroundstringsurfacestringtextstringmutedstringborderstringbuttonTextstringradiusintegerbuttonRadiusintegerfont"system" | "humanist" | "geometric" | "serif" | "mono"widthintegershowLogobooleanaccentBarboolean
blocksobject[]required
dmTextstringfiltersobjectrequiredactiveOnlybooleanvariantIdsvar_…[]purchasedAfterstring | nullpurchasedBeforestring | nullmarketingOnlyboolean
fileobject | nullshowInLibraryboolean
Response TestBroadcastResponse
sentTostringrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/test" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/test', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/test",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": False,
"discord": False,
"telegram": False
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": None,
"showInLibrary": True
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/test", strings.NewReader(`{
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Whether the product’s downloads are marked per buyer, and how
/v1/store/products/{productId}/watermarkOr name the store: GET /v1/stores/{storeId}/products/{productId}/watermark
Parameters
productIdprd_…pathrequired
Response ProductWatermark
productIdProductIdrequiredsettingsWatermarkSettingsrequiredmarkedintegerrequiredlastMarkedAtTimestamp | nullrequiredfilesobject[]requirednamestringrequiredfilenamestringrequiredkindWatermarkKind | nullrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Turn per-buyer watermarks on or off for PDFs, images, ZIP archives and text files
/v1/store/products/{productId}/watermarkOr name the store: PUT /v1/stores/{storeId}/products/{productId}/watermark
Parameters
productIdprd_…pathrequired
Body
enabledbooleanpdfbooleanimagebooleanarchivebooleantextbooleanlabel"email" | "order" | "code"
Response ProductWatermark
productIdProductIdrequiredsettingsWatermarkSettingsrequiredmarkedintegerrequiredlastMarkedAtTimestamp | nullrequiredfilesobject[]requirednamestringrequiredfilenamestringrequiredkindWatermarkKind | nullrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": false,
"pdf": true,
"image": true,
"archive": true,
"text": true,
"label": "email"
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": false,
"pdf": true,
"image": true,
"archive": true,
"text": true,
"label": "email"
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"enabled": False,
"pdf": True,
"image": True,
"archive": True,
"text": True,
"label": "email"
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/watermark", strings.NewReader(`{
"enabled": false,
"pdf": true,
"image": true,
"archive": true,
"text": true,
"label": "email"
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Pay what you want for updates (owners chip in) and for renewals (Extend at a price the buyer picks)
/v1/store/products/{productId}/update-supportOr name the store: GET /v1/stores/{storeId}/products/{productId}/update-support
Parameters
productIdprd_…pathrequired
Response UpdateSupportSettings
enabledbooleanrequiredminimumMinorMinorUnitsrequiredsuggestedMinorMinorUnitsrequiredheadingstringrequiredmessagestringrequiredrenewalPwywbooleanrequiredrenewalMinimumPctintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Save pay what you want for updates and renewals
/v1/store/products/{productId}/update-supportOr name the store: PUT /v1/stores/{storeId}/products/{productId}/update-support
Parameters
productIdprd_…pathrequired
Body
enabledbooleanminimumMinorintegersuggestedMinorintegerheadingstringmessagestringrenewalPwywbooleanrenewalMinimumPctinteger
Response UpdateSupportSettings
enabledbooleanrequiredminimumMinorMinorUnitsrequiredsuggestedMinorMinorUnitsrequiredheadingstringrequiredmessagestringrequiredrenewalPwywbooleanrequiredrenewalMinimumPctintegerrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": false,
"minimumMinor": 0,
"suggestedMinor": 500,
"heading": "Support the next update",
"message": "Like the updates? Chip in what you want. You keep everything you own either way.",
"renewalPwyw": false,
"renewalMinimumPct": 50
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": false,
"minimumMinor": 0,
"suggestedMinor": 500,
"heading": "Support the next update",
"message": "Like the updates? Chip in what you want. You keep everything you own either way.",
"renewalPwyw": false,
"renewalMinimumPct": 50
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"enabled": False,
"minimumMinor": 0,
"suggestedMinor": 500,
"heading": "Support the next update",
"message": "Like the updates? Chip in what you want. You keep everything you own either way.",
"renewalPwyw": False,
"renewalMinimumPct": 50
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/update-support", strings.NewReader(`{
"enabled": false,
"minimumMinor": 0,
"suggestedMinor": 500,
"heading": "Support the next update",
"message": "Like the updates? Chip in what you want. You keep everything you own either way.",
"renewalPwyw": false,
"renewalMinimumPct": 50
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
The Telegram group or channel this product invites buyers to, and how long access lasts
/v1/store/products/{productId}/telegram-accessOr name the store: GET /v1/stores/{storeId}/products/{productId}/telegram-access
Parameters
productIdprd_…pathrequired
Response CommunityProductView
settingsCommunityAccessSettingsrequiredbotobjectrequiredconnectedbooleanrequiredusernamestringrequired
mode"live" | "simulated"requiredgrantsobjectrequiredactiveintegerrequiredwaitingintegerrequiredremovedintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Save Telegram access for a product (the bot must be an admin of the chat who can invite and remove members)
/v1/store/products/{productId}/telegram-accessOr name the store: PUT /v1/stores/{storeId}/products/{productId}/telegram-access
Parameters
productIdprd_…pathrequired
Body
enabledbooleanchatIdstring | nullchatTitlestringchatType"group" | "supergroup" | "channel" | nullduration"auto" | "fixed" | "lifetime"fixedDaysinteger | nullremoveOnRefundbooleanremoveOnChargebackbooleanremoveOnExpirybooleaninviteHoursinteger
Response CommunityProductView
settingsCommunityAccessSettingsrequiredbotobjectrequiredconnectedbooleanrequiredusernamestringrequired
mode"live" | "simulated"requiredgrantsobjectrequiredactiveintegerrequiredwaitingintegerrequiredremovedintegerrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": false,
"chatId": null,
"chatTitle": "",
"chatType": null,
"duration": "auto",
"fixedDays": null,
"removeOnRefund": true,
"removeOnChargeback": true,
"removeOnExpiry": true,
"inviteHours": 24
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"enabled": false,
"chatId": null,
"chatTitle": "",
"chatType": null,
"duration": "auto",
"fixedDays": null,
"removeOnRefund": true,
"removeOnChargeback": true,
"removeOnExpiry": true,
"inviteHours": 24
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"enabled": False,
"chatId": None,
"chatTitle": "",
"chatType": None,
"duration": "auto",
"fixedDays": None,
"removeOnRefund": True,
"removeOnChargeback": True,
"removeOnExpiry": True,
"inviteHours": 24
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/telegram-access", strings.NewReader(`{
"enabled": false,
"chatId": null,
"chatTitle": "",
"chatType": null,
"duration": "auto",
"fixedDays": null,
"removeOnRefund": true,
"removeOnChargeback": true,
"removeOnExpiry": true,
"inviteHours": 24
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Queue a product update for 10 seconds (undo window), then post it like sendBroadcast
/v1/store/products/{productId}/broadcasts/queueOr name the store: POST /v1/stores/{storeId}/products/{productId}/broadcasts/queue
Parameters
productIdprd_…pathrequired
Body
titlestringrequiredversionstringchangelogstringchannelsobjectrequiredemailbooleanrequireddiscordbooleanrequiredtelegrambooleanrequired
docobjectrequiredversionnumbersubjectstringrequiredpreheaderstringstyleobjectaccentstring | nullbackgroundstringsurfacestringtextstringmutedstringborderstringbuttonTextstringradiusintegerbuttonRadiusintegerfont"system" | "humanist" | "geometric" | "serif" | "mono"widthintegershowLogobooleanaccentBarboolean
blocksobject[]required
dmTextstringfiltersobjectrequiredactiveOnlybooleanvariantIdsvar_…[]purchasedAfterstring | nullpurchasedBeforestring | nullmarketingOnlyboolean
fileobject | nullshowInLibraryboolean
Response PendingAction
idPendingActionIdrequiredkindPendingActionKindrequiredlabelstringrequiredstatePendingActionStaterequiredcommitAtTimestamprequiredcreatedAtTimestamprequiredsettledAtTimestamp | nullrequirederrorstringrequiredtargetobjectrequiredkind"order" | "campaign" | "product" | "products" | "discounts"requiredidstringrequired
actorNamestringrequiredminebooleanrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/queue" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/queue', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/queue",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": False,
"discord": False,
"telegram": False
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": None,
"showInLibrary": True
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/broadcasts/queue", strings.NewReader(`{
"title": "string",
"version": "",
"changelog": "",
"channels": {
"email": false,
"discord": false,
"telegram": false
},
"doc": {
"subject": "string",
"blocks": [
{
"id": "string",
"type": "heading",
"text": "string"
}
]
},
"dmText": "",
"filters": {},
"file": null,
"showInLibrary": true
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
Queue deleting products for 10 seconds (undo window)
/v1/store/products/bulk-delete-queueOr name the store: POST /v1/stores/{storeId}/products/bulk-delete-queue
Body
productIdsprd_…[]required
Response PendingAction
idPendingActionIdrequiredkindPendingActionKindrequiredlabelstringrequiredstatePendingActionStaterequiredcommitAtTimestamprequiredcreatedAtTimestamprequiredsettledAtTimestamp | nullrequirederrorstringrequiredtargetobjectrequiredkind"order" | "campaign" | "product" | "products" | "discounts"requiredidstringrequired
actorNamestringrequiredminebooleanrequired
Example
curl -X POST "https://api.shopfa.st/v1/store/products/bulk-delete-queue" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"productIds": [
"prd_0123456789abcdefghjk"
]
}'const res = await fetch('https://api.shopfa.st/v1/store/products/bulk-delete-queue', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"productIds": [
"prd_0123456789abcdefghjk"
]
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"POST",
"https://api.shopfa.st/v1/store/products/bulk-delete-queue",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"productIds": [
"prd_0123456789abcdefghjk"
]
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/products/bulk-delete-queue", strings.NewReader(`{
"productIds": [
"prd_0123456789abcdefghjk"
]
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Try it with your key
The product's one status: badge, label, note (the open incident's title while one is open) and auto-pause
/v1/store/products/{productId}/statusOr name the store: GET /v1/stores/{storeId}/products/{productId}/status
Parameters
productIdprd_…pathrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/status" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/status', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/status",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/status", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Auto-renew for one product: whether buyers can opt in, the dunning schedule and who renews
/v1/store/products/{productId}/auto-renewOr name the store: GET /v1/stores/{storeId}/products/{productId}/auto-renew
Parameters
productIdprd_…pathrequired
Response ProductAutoRenewView
settingsAutoRenewProductSettingsrequiredeligiblebooleanrequiredreasonstringrequiredoptionsobject[]requirednamestringrequiredeverystringrequired
renewingMethodsstring[]requiredactiveintegerrequiredretryingintegerrequired
Example
curl "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew" \
-H "Authorization: Bearer $SHOPFAST_API_KEY"const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
},
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"GET",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("GET", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
res, err := http.DefaultClient.Do(req)Try it with your key
Allow auto-renew on a subscription or duration product and set its retry days
/v1/store/products/{productId}/auto-renewOr name the store: PUT /v1/stores/{storeId}/products/{productId}/auto-renew
Parameters
productIdprd_…pathrequired
Body
allowedbooleanrequiredretryDaysinteger[]requiredgraceDaysintegerrequired
Response ProductAutoRenewView
settingsAutoRenewProductSettingsrequiredeligiblebooleanrequiredreasonstringrequiredoptionsobject[]requirednamestringrequiredeverystringrequired
renewingMethodsstring[]requiredactiveintegerrequiredretryingintegerrequired
Example
curl -X PUT "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew" \
-H "Authorization: Bearer $SHOPFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"allowed": false,
"retryDays": [
1
],
"graceDays": 0
}'const res = await fetch('https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew', {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"allowed": false,
"retryDays": [
1
],
"graceDays": 0
}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const data = await res.json();import os, requests
res = requests.request(
"PUT",
"https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew",
headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
json={
"allowed": False,
"retryDays": [
1
],
"graceDays": 0
},
)
res.raise_for_status()
data = res.json()req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/products/prd_0123456789abcdefghjk/auto-renew", strings.NewReader(`{
"allowed": false,
"retryDays": [
1
],
"graceDays": 0
}`))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)