Docs
Dashboard
On this page

    Popups

    8 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.

    Popup offers with impressions and conversions per variant (last 30 days)

    GET/v1/store/popups

    Or name the store: GET /v1/stores/{storeId}/popups

    marketing:readrole: marketing:readlistPopups

    Parameters

    • status"all" | "live" | "draft" | "paused" | "archived"query

    Response ListPopupsResponse

    • itemsPopup[]required
    • countsobjectrequired
      • allintegerrequired
      • liveintegerrequired
      • draftintegerrequired
      • pausedintegerrequired
      • archivedintegerrequired

    Example

    curl "https://api.shopfa.st/v1/store/popups" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/popups', {
      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/popups",
        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/popups", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Create a popup offer

    POST/v1/store/popups

    Or name the store: POST /v1/stores/{storeId}/popups

    marketing:writerole: marketing:writecreatePopup

    Body

    • namestringrequired
    • kind"coupon" | "email" | "exit" | "upsell" | "announcement"required
    • status"draft" | "live" | "paused" | "archived"required
    • triggerobjectrequired
      • kind"delay" | "scroll" | "exit" | "add_to_cart" | "page_views"required
      • delaySecondsinteger
      • scrollPercentinteger
      • pageViewsinteger
      • exitOnMobileboolean
    • targetingobjectrequired
      • pages"home" | "product" | "collection" | "list-collections" | "cart" | "page" | "search" | "reviews" | "other"[]
      • productHandlesstring[]
      • collectionHandlesstring[]
      • urlContainsstring[]
      • urlExcludesstring[]
      • devices"all" | "desktop" | "mobile"
      • visitors"all" | "new" | "returning"
      • buyers"all" | "buyers" | "non_buyers"
      • cart"any" | "empty" | "has_items"
      • utmSourcestring[]
      • utmMediumstring[]
      • utmCampaignstring[]
    • frequencyobjectrequired
      • showAgainAfterDaysinteger
      • maxShowsinteger | null
      • stopAfterConversionboolean
    • variantsobject[]required
      • key"a" | "b" | "c"required
      • namestringrequired
      • weightintegerrequired
      • contentobjectrequired
        • eyebrowstring
        • headingstringrequired
        • bodystring
        • ctaLabelstring
        • ctaLinkstring
        • dismissLabelstring
        • couponMode"none" | "code" | "unique"
        • discountIddsc_… | null
        • revealAfterEmailboolean
        • emailCaptureboolean
        • emailPlaceholderstring
        • consentLabelstring
        • requireConsentboolean
        • submitLabelstring
        • successHeadingstring
        • successBodystring
        • timerMinutesinteger | null
        • upsellHandlestring | null
      • designobjectrequired
        • layout"modal" | "split" | "corner" | "bar" | "sheet"
        • position"center" | "bottom-right" | "bottom-left" | "top" | "bottom"
        • surface"store" | "light" | "dark"
        • accentstring | null
        • radiusinteger
        • motion"rise" | "scale" | "slide" | "fade"
        • width"sm" | "md" | "lg"
        • imageUrlstring | null
        • backdropinteger
        • showCloseboolean
    • startsAtstring | null
    • endsAtstring | null
    • priorityinteger

    Response Popup

    • namestringrequired
    • kindPopupKindrequired
    • statusPopupStatusrequired
    • triggerPopupTriggerrequired
    • targetingPopupTargetingrequired
    • frequencyPopupFrequencyrequired
    • variantsPopupVariant[]required
    • startsAtTimestamp | nullrequired
    • endsAtTimestamp | nullrequired
    • priorityintegerrequired
    5 more fields
    • idPopupIdrequired
    • showingbooleanrequired
    • statsPopupVariantStats[]required
    • createdAtTimestamprequired
    • updatedAtTimestamprequired

    Example

    curl -X POST "https://api.shopfa.st/v1/store/popups" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "string",
      "kind": "coupon",
      "status": "draft",
      "trigger": {
        "kind": "delay"
      },
      "targeting": {},
      "frequency": {},
      "variants": [
        {
          "key": "a",
          "name": "string",
          "weight": 0,
          "content": {
            "heading": "string"
          },
          "design": {}
        }
      ],
      "startsAt": null,
      "endsAt": null,
      "priority": 50
    }'
    const res = await fetch('https://api.shopfa.st/v1/store/popups', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "name": "string",
        "kind": "coupon",
        "status": "draft",
        "trigger": {
          "kind": "delay"
        },
        "targeting": {},
        "frequency": {},
        "variants": [
          {
            "key": "a",
            "name": "string",
            "weight": 0,
            "content": {
              "heading": "string"
            },
            "design": {}
          }
        ],
        "startsAt": null,
        "endsAt": null,
        "priority": 50
      }),
    });
    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/popups",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
        json={
          "name": "string",
          "kind": "coupon",
          "status": "draft",
          "trigger": {
            "kind": "delay"
          },
          "targeting": {},
          "frequency": {},
          "variants": [
            {
              "key": "a",
              "name": "string",
              "weight": 0,
              "content": {
                "heading": "string"
              },
              "design": {}
            }
          ],
          "startsAt": None,
          "endsAt": None,
          "priority": 50
        },
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/popups", strings.NewReader(`{
      "name": "string",
      "kind": "coupon",
      "status": "draft",
      "trigger": {
        "kind": "delay"
      },
      "targeting": {},
      "frequency": {},
      "variants": [
        {
          "key": "a",
          "name": "string",
          "weight": 0,
          "content": {
            "heading": "string"
          },
          "design": {}
        }
      ],
      "startsAt": null,
      "endsAt": null,
      "priority": 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

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    One popup with its daily series and recent email signups

    GET/v1/store/popups/{popupId}

    Or name the store: GET /v1/stores/{storeId}/popups/{popupId}

    marketing:readrole: marketing:readgetPopup

    Parameters

    • popupIdpop_…pathrequired
    • daysinteger | stringquery

    Response PopupDetail

    • popupPopuprequired
    • seriesobject[]required
      • dateIsoDaterequired
      • keyPopupVariantKeyrequired
      • impressionsintegerrequired
      • conversionsintegerrequired
    • leadsobject[]required
      • emailEmailrequired
      • variantPopupVariantKeyrequired
      • consentbooleanrequired
      • codestringrequired
      • createdAtTimestamprequired
    • leadCountintegerrequired

    Example

    curl "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/popups/pop_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/popups/pop_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/popups/pop_0123456789abcdefghjk", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Save a popup offer

    PUT/v1/store/popups/{popupId}

    Or name the store: PUT /v1/stores/{storeId}/popups/{popupId}

    marketing:writerole: marketing:writesavePopup

    Parameters

    • popupIdpop_…pathrequired

    Body

    • namestringrequired
    • kind"coupon" | "email" | "exit" | "upsell" | "announcement"required
    • status"draft" | "live" | "paused" | "archived"required
    • triggerobjectrequired
      • kind"delay" | "scroll" | "exit" | "add_to_cart" | "page_views"required
      • delaySecondsinteger
      • scrollPercentinteger
      • pageViewsinteger
      • exitOnMobileboolean
    • targetingobjectrequired
      • pages"home" | "product" | "collection" | "list-collections" | "cart" | "page" | "search" | "reviews" | "other"[]
      • productHandlesstring[]
      • collectionHandlesstring[]
      • urlContainsstring[]
      • urlExcludesstring[]
      • devices"all" | "desktop" | "mobile"
      • visitors"all" | "new" | "returning"
      • buyers"all" | "buyers" | "non_buyers"
      • cart"any" | "empty" | "has_items"
      • utmSourcestring[]
      • utmMediumstring[]
      • utmCampaignstring[]
    • frequencyobjectrequired
      • showAgainAfterDaysinteger
      • maxShowsinteger | null
      • stopAfterConversionboolean
    • variantsobject[]required
      • key"a" | "b" | "c"required
      • namestringrequired
      • weightintegerrequired
      • contentobjectrequired
        • eyebrowstring
        • headingstringrequired
        • bodystring
        • ctaLabelstring
        • ctaLinkstring
        • dismissLabelstring
        • couponMode"none" | "code" | "unique"
        • discountIddsc_… | null
        • revealAfterEmailboolean
        • emailCaptureboolean
        • emailPlaceholderstring
        • consentLabelstring
        • requireConsentboolean
        • submitLabelstring
        • successHeadingstring
        • successBodystring
        • timerMinutesinteger | null
        • upsellHandlestring | null
      • designobjectrequired
        • layout"modal" | "split" | "corner" | "bar" | "sheet"
        • position"center" | "bottom-right" | "bottom-left" | "top" | "bottom"
        • surface"store" | "light" | "dark"
        • accentstring | null
        • radiusinteger
        • motion"rise" | "scale" | "slide" | "fade"
        • width"sm" | "md" | "lg"
        • imageUrlstring | null
        • backdropinteger
        • showCloseboolean
    • startsAtstring | null
    • endsAtstring | null
    • priorityinteger

    Response Popup

    • namestringrequired
    • kindPopupKindrequired
    • statusPopupStatusrequired
    • triggerPopupTriggerrequired
    • targetingPopupTargetingrequired
    • frequencyPopupFrequencyrequired
    • variantsPopupVariant[]required
    • startsAtTimestamp | nullrequired
    • endsAtTimestamp | nullrequired
    • priorityintegerrequired
    5 more fields
    • idPopupIdrequired
    • showingbooleanrequired
    • statsPopupVariantStats[]required
    • createdAtTimestamprequired
    • updatedAtTimestamprequired

    Example

    curl -X PUT "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "string",
      "kind": "coupon",
      "status": "draft",
      "trigger": {
        "kind": "delay"
      },
      "targeting": {},
      "frequency": {},
      "variants": [
        {
          "key": "a",
          "name": "string",
          "weight": 0,
          "content": {
            "heading": "string"
          },
          "design": {}
        }
      ],
      "startsAt": null,
      "endsAt": null,
      "priority": 50
    }'
    const res = await fetch('https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk', {
      method: 'PUT',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "name": "string",
        "kind": "coupon",
        "status": "draft",
        "trigger": {
          "kind": "delay"
        },
        "targeting": {},
        "frequency": {},
        "variants": [
          {
            "key": "a",
            "name": "string",
            "weight": 0,
            "content": {
              "heading": "string"
            },
            "design": {}
          }
        ],
        "startsAt": null,
        "endsAt": null,
        "priority": 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/popups/pop_0123456789abcdefghjk",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
        json={
          "name": "string",
          "kind": "coupon",
          "status": "draft",
          "trigger": {
            "kind": "delay"
          },
          "targeting": {},
          "frequency": {},
          "variants": [
            {
              "key": "a",
              "name": "string",
              "weight": 0,
              "content": {
                "heading": "string"
              },
              "design": {}
            }
          ],
          "startsAt": None,
          "endsAt": None,
          "priority": 50
        },
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("PUT", "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk", strings.NewReader(`{
      "name": "string",
      "kind": "coupon",
      "status": "draft",
      "trigger": {
        "kind": "delay"
      },
      "targeting": {},
      "frequency": {},
      "variants": [
        {
          "key": "a",
          "name": "string",
          "weight": 0,
          "content": {
            "heading": "string"
          },
          "design": {}
        }
      ],
      "startsAt": null,
      "endsAt": null,
      "priority": 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

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Delete a popup with its stats (email signups stay in the export until then)

    DELETE/v1/store/popups/{popupId}

    Or name the store: DELETE /v1/stores/{storeId}/popups/{popupId}

    marketing:writerole: marketing:writedeletePopup

    Parameters

    • popupIdpop_…pathrequired

    Response Ok

    • okbooleanrequired

    Example

    curl -X DELETE "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/popups/pop_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/popups/pop_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/popups/pop_0123456789abcdefghjk", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Publish, pause or archive a popup

    POST/v1/store/popups/{popupId}/status

    Or name the store: POST /v1/stores/{storeId}/popups/{popupId}/status

    marketing:writerole: marketing:writesetPopupStatus

    Parameters

    • popupIdpop_…pathrequired

    Body

    • status"draft" | "live" | "paused" | "archived"required

    Response Popup

    • namestringrequired
    • kindPopupKindrequired
    • statusPopupStatusrequired
    • triggerPopupTriggerrequired
    • targetingPopupTargetingrequired
    • frequencyPopupFrequencyrequired
    • variantsPopupVariant[]required
    • startsAtTimestamp | nullrequired
    • endsAtTimestamp | nullrequired
    • priorityintegerrequired
    5 more fields
    • idPopupIdrequired
    • showingbooleanrequired
    • statsPopupVariantStats[]required
    • createdAtTimestamprequired
    • updatedAtTimestamprequired

    Example

    curl -X POST "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk/status" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "status": "draft"
    }'
    const res = await fetch('https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk/status', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.SHOPFAST_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        "status": "draft"
      }),
    });
    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/popups/pop_0123456789abcdefghjk/status",
        headers={"Authorization": f"Bearer {os.environ['SHOPFAST_API_KEY']}"},
        json={
          "status": "draft"
        },
    )
    res.raise_for_status()
    data = res.json()
    req, _ := http.NewRequest("POST", "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk/status", strings.NewReader(`{
      "status": "draft"
    }`))
    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

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Copy a popup as a draft

    POST/v1/store/popups/{popupId}/duplicate

    Or name the store: POST /v1/stores/{storeId}/popups/{popupId}/duplicate

    marketing:writerole: marketing:writeduplicatePopup

    Parameters

    • popupIdpop_…pathrequired

    Response Popup

    • namestringrequired
    • kindPopupKindrequired
    • statusPopupStatusrequired
    • triggerPopupTriggerrequired
    • targetingPopupTargetingrequired
    • frequencyPopupFrequencyrequired
    • variantsPopupVariant[]required
    • startsAtTimestamp | nullrequired
    • endsAtTimestamp | nullrequired
    • priorityintegerrequired
    5 more fields
    • idPopupIdrequired
    • showingbooleanrequired
    • statsPopupVariantStats[]required
    • createdAtTimestamprequired
    • updatedAtTimestamprequired

    Example

    curl -X POST "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk/duplicate" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/popups/pop_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/popups/pop_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/popups/pop_0123456789abcdefghjk/duplicate", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Email signups of a popup as CSV, with consent and the code each got

    GET/v1/store/popups/{popupId}/leads/export

    Or name the store: GET /v1/stores/{storeId}/popups/{popupId}/leads/export

    marketing:readrole: marketing:readexportPopupLeads

    Parameters

    • popupIdpop_…pathrequired

    Response FileExport

    • filenamestringrequired
    • contentTypestringrequired
    • bodystringrequired
    • rowsintegerrequired

    Example

    curl "https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk/leads/export" \
      -H "Authorization: Bearer $SHOPFAST_API_KEY"
    const res = await fetch('https://api.shopfa.st/v1/store/popups/pop_0123456789abcdefghjk/leads/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/popups/pop_0123456789abcdefghjk/leads/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/popups/pop_0123456789abcdefghjk/leads/export", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("SHOPFAST_API_KEY"))
    res, err := http.DefaultClient.Do(req)
    Try it with your key

    Use a test key on a development store. The key stays in this tab (sessionStorage) and is sent only to the base URL above.

    Was this page helpful?