I generate a lot of demo stores up till today I thought there was infact no limit to the number of websites you could connect to SureCart after all i’ve been doing it for months, well it turns out there is a limit I hit it for the first time today.

The magic number is 50 one you have 50 webhooks it wont let you add anymore so by that reasoning you have a 50 useable limit for connected stores. Now I don’t think anyone is going to have 50 connected stores but it happened here due to demo stores.
Now I don’t want to delete all those stores by hand (95% of them are dead and gone) the others I can manually reconnect quicker.
So i looked at the API and it turns out even webhooks are in the API scope so i set about writing a little bash script to clear them out in a jiffy. This script should be 100% portable too so it will work on Windows (git bash in my case) macOS and Linux
#!/usr/bin/env sh
# Portable (POSIX sh) script to list and delete all SureCart webhook endpoints.
# Works on Linux, macOS, and Windows Git Bash/MSYS/Cygwin.
# How to USE
# export SURECART_API_KEY="sc_xxx"
# chmod +x clear-surecart-webhooks.sh
# # See what would be deleted (default dry-run):
# ./clear-surecart-webhooks.sh
# # Actually delete:
# ./clear-surecart-webhooks.sh --yes
# # Quiet:
# ./clear-surecart-webhooks.sh --yes --silent
set -eu
API_BASE="https://api.surecart.com/v1"
API_KEY="${SURECART_API_KEY:-}"
DRY_RUN=1
SILENT=0
LIMIT=100
usage() {
cat <<'EOF'
Usage: clear-surecart-webhooks.sh [--yes] [--silent] [-h|--help]
Deletes ALL SureCart webhook endpoints in your account.
Environment:
SURECART_API_KEY Your SureCart API key (required)
Flags:
--yes Perform deletions (without this it's a dry run)
--silent Less output
-h|--help Show this help
EOF
}
# --- parse args (POSIX) ---
while [ "${1-}" ]; do
case "$1" in
--yes) DRY_RUN=0 ;;
--silent) SILENT=1 ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown argument: $1" >&2; usage; exit 1 ;;
esac
shift
done
# --- checks ---
[ -n "$API_KEY" ] || { echo "Error: SURECART_API_KEY is not set." >&2; exit 1; }
command -v jq >/dev/null 2>&1 || { echo "Error: 'jq' is required." >&2; exit 1; }
command -v curl >/dev/null 2>&1 || { echo "Error: 'curl' is required." >&2; exit 1; }
# --- headers ---
HDR_AUTH="Authorization: Bearer ${API_KEY}"
HDR_ACCEPT="Accept: application/json"
HDR_CT="Content-Type: application/json"
# --- temp file and cleanup ---
IDS_FILE="$(mktemp 2>/dev/null || echo "/tmp/clear-surecart-webhooks.$$")"
cleanup() { rm -f "$IDS_FILE"; }
trap cleanup EXIT HUP INT TERM
# --- paginate + collect IDs safely ---
PAGE=1
while : ; do
RESP="$(curl -sS -H "$HDR_AUTH" -H "$HDR_CT" -H "$HDR_ACCEPT" \
-- "${API_BASE}/webhook_endpoints?limit=${LIMIT}&page=${PAGE}")" || {
echo "Error: request failed on page ${PAGE}." >&2; exit 1; }
# Validate JSON
echo "$RESP" | jq -e . >/dev/null 2>&1 || {
echo "Error: non-JSON response on page ${PAGE}." >&2; exit 1; }
# Extract IDs; strip any CRs to be Windows-safe
PAGE_COUNT="$(printf '%s' "$RESP" | jq '[.data[]?.id] | length')"
if [ "${PAGE_COUNT:-0}" -eq 0 ]; then
break
fi
printf '%s' "$RESP" | jq -r '.data[]?.id // empty' | tr -d '\r' >> "$IDS_FILE"
PAGE=$((PAGE + 1))
done
TOTAL="$(wc -l < "$IDS_FILE" | tr -d '[:space:]')"
[ "${TOTAL:-0}" -gt 0 ] || { [ "$SILENT" -eq 1 ] || echo "Found 0 webhook endpoint(s)."; exit 0; }
[ "$SILENT" -eq 1 ] || echo "Found ${TOTAL} webhook endpoint(s)."
# --- dry run ---
if [ "$DRY_RUN" -eq 1 ]; then
if [ "$SILENT" -eq 0 ]; then
echo "Dry run: would delete the following IDs:"
sed 's/^/ - /' "$IDS_FILE"
echo "Run again with --yes to actually delete."
else
cat "$IDS_FILE"
fi
exit 0
fi
# --- destructive phase ---
ERRORS=0
# Read line-by-line, preserving text and stripping CR/LF defensively
# (avoid IFS tricks to keep IDs exact)
while IFS= read -r RAW_ID || [ -n "$RAW_ID" ]; do
ID_CLEAN="$(printf '%s' "$RAW_ID" | tr -d '\r\n')"
[ "$SILENT" -eq 1 ] || echo "Deleting webhook endpoint: ${ID_CLEAN}"
# First attempt
HTTP_CODE="$(curl -sS -o /dev/null -w '%{http_code}' \
-H "$HDR_AUTH" -H "$HDR_CT" -H "$HDR_ACCEPT" -X DELETE \
-- "${API_BASE}/webhook_endpoints/${ID_CLEAN}")" || HTTP_CODE="000"
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "204" ]; then
[ "$SILENT" -eq 1 ] || echo " -> deleted"
continue
fi
if [ "$HTTP_CODE" = "429" ]; then
[ "$SILENT" -eq 1 ] || echo " -> rate-limited; sleeping 2s and retrying…"
sleep 2
HTTP_CODE2="$(curl -sS -o /dev/null -w '%{http_code}' \
-H "$HDR_AUTH" -H "$HDR_CT" -H "$HDR_ACCEPT" -X DELETE \
-- "${API_BASE}/webhook_endpoints/${ID_CLEAN}")" || HTTP_CODE2="000"
if [ "$HTTP_CODE2" = "200" ] || [ "$HTTP_CODE2" = "204" ]; then
[ "$SILENT" -eq 1 ] || echo " -> deleted (after retry)"
else
echo " -> failed with HTTP ${HTTP_CODE2}" >&2
ERRORS=$((ERRORS + 1))
fi
else
echo " -> failed with HTTP ${HTTP_CODE}" >&2
ERRORS=$((ERRORS + 1))
fi
done < "$IDS_FILE"
if [ "$ERRORS" -gt 0 ]; then
echo "Completed with ${ERRORS} error(s)." >&2
exit 1
fi
[ "$SILENT" -eq 1 ] || echo "All webhook endpoints deleted."
PHPWith the above script I was able to clear them out in seconds and now I don’t need to delete my store and remake all my products for my demos and demo videos.
That to me is a win win situation.