| Warehouse | Status | ELITE boxes | PRO boxes | ORIGINAL boxes | Value at cost |
|---|---|---|---|---|---|
| UK — London Heathrow | Sellable | 1,213 | 1,167 | 814 | £9,864 |
| FR — Vendée | Sellable | 3,887 | 3,471 | 1,010 | £27,980 |
| DE — Saxony-Anhalt (Halle) | 🔒 LOCKED (FBO) | 854 | 723 | 1,459 | £8,505 |
| UK — Reserved / Active Picking | Reserved | — | — | — | £117.20 |
| Total | 5,954 | 5,361 | 3,283 | £46,466.40 | |
All 8,082 units in the Saxony-Anhalt (Halle) warehouse are in Unavailable
status due to an ongoing FBO (Fulfilment-by-Byrd) registration block. Stock cannot ship until registration
completes.
Options: (1) Wait it out — registration may resolve without intervention. (2) Request bulk ship-back to UK warehouse for sellable stock clearance. (3) Pause DE ad spend and rotate budget to UK/FR while blocked.
At cost value £8,505 is carried as a write-down risk until status changes.
DE FBO registration is locked, so DE customer orders are currently being fulfilled from the FR warehouse. FR stock is therefore depleting at the combined FR + DE demand rate — not just FR. The table below reflects this. When DE FBO unblocks, the routing reverses: FR reverts to FR-only burn, DE warehouse starts depleting its current locked stock.
Why this matters: Byrd stocks only single packs (30-cap boxes). Bundle orders (2-month, 3-month, 6-month, Starter) get assembled at the warehouse from those single packs. This table attributes all bundle demand back to single-pack consumption, so the 'days left' figure reflects real burn rate. Thresholds: CRITICAL < 14d · LOW < 30d · OK < 60d · HEALTHY ≥ 60d.
| Market | Class | Physical | Sellable | Effective burn /90d | Burn /day | Days left | Status |
|---|---|---|---|---|---|---|---|
| UK | ORIGINAL | 814 | 811 | 1,476 | 16.40 | 50 | OK |
| UK | PRO | 1,017 | 1,014 | 6,008 | 66.76 | 15 | LOW |
| UK | ELITE | 1,141 | 1,117 | 3,538 | 39.31 | 28 | LOW |
| FR (FR+DE) | ORIGINAL | 1,010 | 1,010 | 684 | 7.60 | 133 | HEALTHY |
| FR (FR+DE) | PRO | 3,277 | 3,277 | 4,922 | 54.69 | 60 | OK |
| FR (FR+DE) | ELITE | 3,544 | 3,544 | 2,985 | 33.17 | 107 | HEALTHY |
| DE | ORIGINAL | 1,459 | 0 | (rerouted to FR) | 0 | 0 | LOCKED |
| DE | PRO | 579 | 0 | (rerouted to FR) | 0 | 0 | LOCKED |
| DE | ELITE | 748 | 0 | (rerouted to FR) | 0 | 0 | LOCKED |
Bundle attribution: -2 bundles count as 2× the base class · -6 as 6× · -12 as 12× · PRO+ELITE combos split N/2 between classes · Starter Bundle = 1 ORIGINAL + 1 PRO + 1 ELITE per unit (confirmed Calum 2026-05-14 — no separate Starter SKU, picked from the three single packs).
Source: Byrd live API pull 2026-05-19 + Shopify 90d sales velocity 2026-05-14.
0712038530489-2 2-month bundle in the last 90 days). Top priority — reorder
immediately.Post-unlock scenario (DE FBO restored): FR reverts to FR-only burn (PRO returns to 190 days). DE warehouse starts depleting its locked 579 PRO boxes at the original 35.98/day → 16 days post-unblock. So you'd need DE PRO reordered shortly BEFORE the unblock, not after, to avoid a same-week DE stockout.
| Market | Active subs | Native MRR | GBP-equiv | Currency | Top intervals |
|---|---|---|---|---|---|
| UK | 2,055 | £49,563 | £49,563 | GBP | 30d×880 · 180d×511 · 90d×373 · 60d×287 |
| DE | 605 | €17,724 | £15,243 | EUR · FX 0.86 | 30d×205 · 180d×166 · 90d×158 · 60d×75 |
| FR | 545 | €16,619 | £14,292 | EUR · FX 0.86 | 30d×229 · 180d×138 · 90d×128 · 60d×48 |
| US | 248 | $9,684 | £7,650 | CAD+USD · FX 0.79 | 30d×116 · 180d×57 · 90d×49 · 60d×26 |
| Total | 3,453 | — | £86,748 | ||
ACTIVE, inflating the headline MRR.
The Shopify reconciliation below is the ground-truth check: it counts actual subscription orders
that hit your store (and were paid) in the last 30 days.
| Market | Seal Active | Expected /30d | Actual Paid /30d | Leakage | Actual Value | GBP-eq |
|---|---|---|---|---|---|---|
| UK | 2,055 | 1,233 | 808 | -34% LOW | £30,548 | £30,548 |
| DE | 605 | 325 | 291 | -10% OK | €15,373 | £13,221 |
| FR | 545 | 290 | 163 | -44% HIGH | €9,781 | £8,412 |
| US | 248 | 140 | 76 | -46% HIGH | $4,275 | £3,377 |
| TOTAL | 3,453 | 1,988 | 1,338 | -33% | — | £55,558 |
Of 3,453 Seal-active subscribers, only 1,338 (39%) generated a paid order in the
last 30 days. Some of this gap is timing (longer-cadence subs aren't due this month), but the
cadence math already accounts for that — actual is still 33% below expected.
The remaining gap is almost certainly dunning leakage: cards declined or expired,
contracts marked ACTIVE in Seal but no longer collecting.
Biggest leakage: US (-46%) and FR (-44%). UK at -34% is also material. DE at -10% is acceptable (within sampling noise). Worth Seal → bookkeeper sweep of subs with ≥2 consecutive failed billing attempts and either retry-or-cancel.
| Window | UK /mo | DE /mo | FR /mo | US /mo | Total GBP-eq /mo | Leakage vs Seal £87K |
|---|---|---|---|---|---|---|
| Last 30 days | £30,548 | €15,373 | €9,781 | $4,275 | £55,558 | -36% |
| Last 60 days (÷2) | £30,206 | €15,575 | €9,547 | $4,217 | £55,143 | -36% |
| Last 90 days (÷3) | £30,964 | €15,449 | €9,478 | $4,567 | £56,009 | -35% |
| Last 180 days (÷6) | £32,775 | €15,586 | €10,073 | $4,404 | £58,321 | -33% |
180-day window catches half-yearly and yearly subs that don't renew within shorter windows. The fact that the gap is the same (33-36%) across all four windows confirms the leakage isn't a timing artifact — long-cadence subs aren't being missed by the 30d view; the missing payments are structural.
| Market | Seal Active | Expected /180d orders | Actual /180d orders | Unique payers /180d | Gap | Value | GBP-eq |
|---|---|---|---|---|---|---|---|
| UK | 2,055 | 7,402 | 4,955 | 2,277 | -33% | £196,649 | £196,649 |
| DE | 605 | 1,938 | 1,715 | 889 | -12% | €93,516 | £80,424 |
| FR | 545 | 1,920 | 1,045 | 540 | -46% | €60,440 | £51,978 |
| US | 248 | 929 | 441 | 193 | -53% | $26,424 | £20,875 |
| TOTAL | 3,453 | 12,189 | 8,156 | 3,899 | -33% | — | £349,926 |
Unique payers /180d (3,899) includes some customers who paid early in the window but have since cancelled. That's why it can exceed Seal's current ACTIVE count. The conservative read is the 90d unique-payer count (2,592) for "still engaged"; the 180d figure is the upper bound on "anyone with recent purchase intent".
US gap widens at longer windows (30d -46% → 180d -53%) — likely a higher share of half-yearly subs that aren't renewing. Worth a focused look at US subs older than 6 months.
Gap is -33% to -36% in every window we measured (30d, 60d, 90d, 180d). If this were a timing issue (long-cadence subs renewing outside the 30d window), the 180d view would have converged. It hasn't. The gap is structural.
Best-practice direction (your question, answered): yes — reduce auto-charge retry count + auto-cancel after the retry window expires. Industry standard is 3-4 retries spread over 14-21 days, then auto-cancel. The 861 subs we identified as "no payment in 90+ days" almost certainly have >10 failed billing attempts each — they should have been auto-cancelled months ago but Seal's default config doesn't enforce it. Tightening the retry settings + a one-off bulk-cancel sweep is the right move.
Seal has a configurable retry engine at
Settings → General Settings → Billing settings, with documented behaviour
(Seal FAQ source):
"If the payment fails on all tries, then the subscription will be cancelled automatically."
Gap #1 — the default retry count is not published. Merchants who never
visited the Billing settings inherit whatever Seal shipped. Could be 5 retries over 35 days,
which leaves every failing sub in ACTIVE limbo for a full billing cycle.
Gap #2 — no intermediate status. Seal returns ACTIVE for
everything from first-charge-succeeded to mid-retry-failing. No way to distinguish via the
merchant API. Other status values exposed: PAUSED, CANCELLED,
EXPIRED. None of them mean "currently in retry / dunning".
Gap #3 — Seal admits sync drift with Shopify (Seal FAQ source): even when Seal cancels a sub and removes it from its dashboard, Shopify can still show the customer as having an active subscription. Documented lag, no resolution recipe.
| Subscription app | Failed-payment status | Default behaviour | Merchant control |
|---|---|---|---|
| Recharge | past_due distinct |
Auto-cancel after max retries, labelled "Failed Payment flow max retries" | Retry schedule configurable |
| Bold Subscriptions | past_due distinct |
Auto-cancel after retries (configurable 1–15). Pause-instead-of-cancel requires opt-in. | Retry count + delay |
| Stripe Billing | past_due distinct |
Marks sub past_due / unpaid after retry window |
Smart Retries + dunning emails |
| Shopify-native subscriptions | past_due distinct |
Auto-cancel or marks suspended after retry window | Configurable per contract |
| Seal Subscriptions (us) | None — all ACTIVE |
ACTIVE through entire retry window. Auto-cancel only AFTER max retries exhausted. | Configurable, but default not published |
Industry norm: ACTIVE = currently paying; dunning/failing subs get a distinct status or are cancelled. Seal's choice to keep everything ACTIVE through retries (with no intermediate visible status) is the design decision driving our 33% inflation.
"Half of my subscriptions don't go through (customer support blames Shopify, Shopify blames the app). The app uncancels and unskips randomly, and charges people when they have already cancelled."
— Grimoire&Alchemy, Shopify App Store, Feb 2025. Status drift in both directions confirmed by an unrelated merchant.
"When our customers unsubscribe from our plan, they are not actually unsubscribed and continue to be charged."
— Terme di Comano Skincare, Shopify App Store, Feb 2025. The inverted sync problem: status says cancelled, billing still runs.
Reddit / Indie Hackers: no specific threads on ACTIVE count inflation surfaced in research. Most merchants wouldn't notice this issue unless they cross-reference Seal against Shopify the way we did — which is the entire reason this dashboard exists.
Source: Shopify App Store — Seal 1-star reviews
· Full research brief at F:/Agentic-OS/projects/ops-finance/seal_dunning_research_2026-05-13.md.
Not supported by evidence — but the design choice IS the structural cause.
There's no evidence Seal programmatically prevents cancellation to inflate vanity metrics. But
the combination of (a) ACTIVE-through-entire-retry-window with no intermediate status,
(b) unpublished default retry count, and (c) documented sync drift with Shopify produces the
same effect: merchants who don't manually audit their book see an ACTIVE count that drifts
higher than reality over time. Industry alternatives don't have this problem because they
either auto-cancel or surface a distinct past_due state.
Our specific exposure: ~1,150–1,200 subscribers in
ACTIVE status who haven't generated a paid order in 90+ days. That's £375K/year
of phantom ARR that's not contributing to cashflow.
The single "active count" question doesn't have one answer — different windows give different truths. The fairest monthly count is Expected /30d (cadence math), because legitimate skipped payments shouldn't be punished. The fairest quarterly count is 90-day unique payers, because it catches longer cadences AND skip-and-resume behaviour.
| Metric | Count | Meaning |
|---|---|---|
| Seal-claimed ACTIVE | 3,453 | Upper bound — includes everyone Seal has marked ACTIVE regardless of payment history |
| Net monthly recurring (Expected /30d cadence math) | 1,988 | The fair monthly active count — each sub weighted by its natural cadence (30d, 60d, 90d, 180d) |
| Net engaged (90-day unique payers) | 2,592 | Anyone who paid at least once in the last 90 days. Catches half-yearly subs + skip-then-resume customers. |
| Strict 30d payers (Shopify-verified) | 1,338 | Cashflow signal — undercounts because half-yearly + bi-monthly subs renew outside the window, AND legitimate skip-this-month customers |
| Probable lapsed / dunning (Seal claim − 90d unique payers) | 861 | Highest-confidence cleanup target — Seal says ACTIVE but no successful payment in 90+ days |
Working figure for accounting / asset valuation: use Net monthly recurring 1,988 as the headline subscriber count. That's the count that produces the expected monthly order volume of 1,988 orders (verified by Shopify reconciliation against cadence math). The 861 probable-lapsed subs are the cleanup priority.
tools/shopify_subscription_verify.py after 7 days to confirm
the ACTIVE count drops and the leakage gap closes.Effort: ~30 min per store · Speed: immediate · Reversibility: low (cancellations are hard to undo per customer — but bulk dunning customers won't notice)
Send the prepared support email asking specifically about:
(1) default retry count, (2) why no intermediate past_due status, (3) why
billing_attempts[].error_code is empty on dunning subs, (4) sync drift with Shopify,
(5) dunning report export, (6) bulk-cleanup tooling. Doesn't fix our exposure but pushes Seal
to fix the product.
Draft saved at F:/Agentic-OS/projects/ops-finance/seal_support_email_2026-05-13.md ·
Effort: 5 min review + send · Outcome: uncertain (depends on Seal's responsiveness)
Build tools/seal_dunning_tagger.py that, weekly per store: pulls all ACTIVE subs
from Seal API, cross-references against last 90 days of Shopify orders, identifies lapsed
cohort, and applies Shopify customer tags per the policy schedule (Day-60 dunning, Day-120
lapsed-winback, Day-180+ dormant). GHL automations fire off each tag transition.
No destructive Seal cancellations (per Calum 2026-05-14) — tags only.
Effort: 2-3 hours to build · Maintenance: low once shipped · Outcome: automatic win-back trigger for every customer who fails a payment, scaled across 4 stores
All three alternatives expose an intermediate past_due status or auto-cancel
after retries — the fundamental design choice driving the inflation is absent. Migration is a
meaningful project: customer-payment-method re-tokenisation, sub-contract re-creation, possible
churn at the switch, 4-store coordination.
Effort: 2-4 weeks engineering · Cost: Recharge/Bold pricing tier · Risk: notable customer-experience friction at migration · Justified when: if Options A-C don't close the gap to <10%
Start with B + C in parallel (email Seal asking about retry defaults + build the tag-and-engage tool). Option A (manual in-app retry-settings tweak) is a quick one-time win that should be done immediately regardless. Skip the in-app bulk-cancel step from Option A — tag instead, per the revised policy.
Only consider D (migration to Recharge/Bold) if Seal's product response on Option B is "no fix planned" AND we observe ongoing transaction-fee bleed from continuing retries against dead cards. Until then, the tag-and-engage approach handles the practical issue without destructive mutations.
| Cohort | Definition | UK | US | DE | FR | Total |
|---|---|---|---|---|---|---|
| Healthy | Paid <30d ago | 732 | 76 | 226 | 152 | 1,186 |
| Skip | Paid 30-90d ago (legitimate cadence gap) | 492 | 56 | 170 | 117 | 835 |
| At-risk | Paid 90-180d ago (concerning) | 315 | 27 | 85 | 84 | 511 |
| Lapsed | Paid 180-365d ago (likely dunning) | 173 | 20 | 59 | 47 | 299 |
| No-history | No Shopify sub orders in 365d (possible email mismatch or genuinely dead) | 344 | 70 | 63 | 147 | 624 |
| TOTAL ACTIVE | (per Seal API) | 2,056 | 249 | 603 | 547 | 3,455 |
Healthy + Skip = 2,021 truly active subscribers (59% of Seal-claimed ACTIVE). At-risk + Lapsed = 810 candidates for the resurrection analysis below. No-history = 624 customers Seal calls ACTIVE but who have never (in 365d) paid via Shopify — most concerning bucket, likely email mismatch or very-long-lapsed.
Method (cadence-aware): for each customer in the At-risk + Lapsed cohort (paid 90-365 days ago, no payment since), inspect their full 365d payment timeline. Did they ever have a silence gap longer than 2× their natural billing cadence (a real missed cycle, not just a normal long-cadence renewal), followed by a successful payment? If yes, they resurrected at least once.
Methodology correction (Calum 2026-05-14): the original v1 analysis used a flat 60-day gap threshold, which incorrectly counted normal 90-day and 180-day cadence renewals as "resurrections". The corrected v2 uses cadence×2 (so a 90-day-cadence sub needs a 180+ day gap to qualify). Old rate: 33.4% (inflated by long-cadence false-positives). True rate: 6.3%.
| Market | Candidates | Resurrected | Rate (v2) | Median lag |
|---|---|---|---|---|
| UK | 488 | 35 | 7.2% | 90 days |
| US | 47 | 3 | 6.4% | 154 days |
| DE | 144 | 10 | 6.9% | 120 days |
| FR | 131 | 3 | 2.3% | 104 days |
| Total | 810 | 51 | 6.3% | ~90-150 days |
Source: tools/seal_resurrection_analysis.py v2 (cadence-aware) · 2026-05-14 ·
365d Shopify lookback · masked-email JSON snapshot at
F:/Agentic-OS/projects/ops-finance/seal_resurrection_2026-05-14.json.
Per Calum 2026-05-14: there's almost no benefit to actually cancelling lapsed Seal subs. The Day-180+ cohort has likely already exhausted Seal's retry mechanism, so they're sitting dormant — not generating ongoing transaction-fee costs. Cancellation is destructive (re-onboarding requires re-tokenising payment, customer checkout friction). Tagging preserves optionality at near-zero cost.
Reporting accuracy is solved at the dashboard layer, not by deleting Seal records. The "true paying subscribers" KPI uses Shopify-verified payments in last 30d, not Seal's inflated ACTIVE count. Seal's ACTIVE count becomes a historical "ever-subscribed" count, not a current-paying count.
Recommended workflow:
lapsed-failed-payments-{com|us|de|fr}. Shopify tags auto-sync to Go High Level.won_back segment for ROI tracking.| Store | Shopify tag | Customers to tag |
|---|---|---|
| UK (.com) | lapsed-failed-payments-com | 832 |
| US | lapsed-failed-payments-us | 117 |
| DE | lapsed-failed-payments-de | 207 |
| FR | lapsed-failed-payments-fr | 278 |
| TOTAL | — | 1,434 |
Tags applied in Shopify auto-sync to GHL — no separate GHL tag step needed. Tool:
tools/seal_dunning_tagger.py (dry-run default; --approve to write).
20 UK at-risk customers tagged in a 2026-05-15 test batch (all verified).
1. CSV write-ahead log --> record INTENT [crash-recoverable] 2. Shopify tagsAdd --> the actual mutation 3. Shopify re-query --> LOCK 2: read-after-write verify 4. CSV outcome --> record VERIFIED result 5. Google Sheet --> mirror verified CSV [reporting only]
The Google Sheet is never in the critical write path — it's a downstream mirror that only ever reflects verified reality. Writing it first would risk the Sheet showing "tagged" for something that didn't land.
| Lock | When | Catches |
|---|---|---|
| Lock 1 — exact match | before write | Ambiguous/duplicate customer records → skipped + logged, never guessed |
| Lock 2 — read-after-write | at write | Mutation silently failed / didn't stick → retry once, then flag UNVERIFIED |
| Lock 3 — reconciliation sweep | after run, anytime | --verify-only re-pulls every CSV row, re-confirms tag live in Shopify |
Lock 2 is deterministic and synchronous — strictly better than a trailing review agent.
The no-history cohort gets ghost protection: emails that don't resolve to a real Shopify
customer are logged no_shopify_match_ghost_NOT_tagged, never tagged.
Earlier assumption "Day-180+ subs have exhausted Seal retries — no fee bleed" is WRONG. Spot-check: 100% of lapsed subs (UK 173/173, DE 59/59) have a future billing date still scheduled, with billing-attempt counts averaging 17 (max 58). Seal keeps retrying indefinitely. There likely IS modest ongoing decline-fee cost (~£0.15/attempt). Doesn't change the tag-first decision, but means cancellation after a failed win-back has a real secondary saving.
Research brief: projects/ops-finance/seal_dunning_research_2026-05-13.md ·
Seal support email draft: seal_support_email_2026-05-13.md.