nohold / docs

Operations

How nohold surfaces operational health and what to do when something needs attention.

How nohold surfaces operational health and what to do when something needs attention.

Reconciliation health card (Pro+)

On the Overview page, the Reconciliation health card surfaces four counts that indicate something needs attention:

CountWhen it's non-zero
Splits stuck pendingSplits in pending status with split_at more than 24 hours ago. Means the split worker started but never finished.
BP sales orders missingSplits older than 1 hour with both bp_immediate_order_id AND bp_deferred_order_id NULL, but Brightpearl credentials ARE connected. Means the BP write should have happened but didn't.
Dead dispatchesOutbound dispatches our queue gave up on after the retry budget was exhausted.
Stale holdsFulfillment holds older than 30 days still in held status. Means either a classifier-config gap or Shopify-side state divergence.

All four counts are per-merchant. If any is non-zero, the badge turns red (N need attention) and the corresponding rows turn red. Colorblind-safe: the text changes too, not just the color.

When everything is zero, the badge is green (All clear). The card still renders; silence isn't the right signal when this is your only proactive ops indicator.

A merchant who hasn't connected Brightpearl yet doesn't see the BP sales orders missing alarm spuriously; that count is gated on credential presence.

The sweeper

nohold runs a background sweeper that periodically recovers stuck work and fires the 30-day FTC notice. It handles:

  • Webhook deliveries that started processing but never completed.
  • Outbound dispatches that didn't get picked up or didn't finish.
  • Billing-cycle resets when a merchant's anniversary rolls over.
  • Trial expiry when a merchant's 14 days are up.
  • The FTC 30-day delay notice for preorders open more than 30 days without a confirmed ship date and without a customer cancel request.

The sweeper is idempotent. A row can't be re-claimed or double-processed by a second invocation. You don't have to trigger anything; it runs in the background and is what catches most transient infrastructure hiccups before they're visible to you.

What if the dashboard health card always shows red?

A few rows in any of these counts is normal: a customer who never replies to a cancel email leaves a stale hold; a Brightpearl outage at midnight leaves dead dispatches. The card's job is to surface signal, not to demand zero.

Worth investigating when:

  • Splits stuck pending > 5. Likely a split-worker config issue (Shopify token expired, scope revoked, classifier choking on a malformed order).
  • BP sales orders missing > 5. Brightpearl outage or auth issue.
  • Dead dispatches > 0. Always worth a look. Dead means the queue gave up; the failure didn't recover on its own.
  • Stale holds > 10. Likely a campaign that's been forgotten or a Shopify-side state divergence. Worth a manual audit.

Email support with the specific count and we'll dig in. For dead dispatches, include the split's order number; we can usually pinpoint the issue from the dispatch row.

When a customer asks for their data

Shopify forwards customer data requests and deletion requests to every installed app, including nohold.

A data request. nohold assembles everything it holds about that customer — the stored order payloads, the split records derived from them, and the notification log — and sends it to us. We forward it to you, normally the same day and always inside the 30 days Shopify allows. You are the data controller, so the reply to your customer comes from you, not from us. If you have not heard from us within a few days of raising one, email hello@nohold.app with your store domain and the customer id.

A deletion request. This one is automatic and needs nothing from you. nohold redacts the customer's name, email, phone, and address across every table that holds them, scoped to the orders Shopify named, within seconds of receiving the request. The split records themselves survive with the personal fields stripped, so your order history stays reconcilable.

Separately, nohold purges personal data from its own operational tables after 90 days regardless of whether anyone asks — webhook payloads, dispatch payloads, and notification recipients all age out.

What about the dispatch DLQ?

When a dispatch exhausts its retry budget, the row lands in the internal dead-letter queue (DLQ). Currently the DLQ is internal-only; there's no merchant-facing UI. We monitor it and proactively reach out if your merchant ID shows up.

A merchant-facing DLQ view is on the V2 list.

On this page