nohold / docs
Internals

API surface

What's exposed to the nohold dashboard.

What's exposed to the nohold dashboard. There's no public-merchant API yet; this page documents what the dashboard can do, useful for understanding the boundaries.

Authentication

Bearer JWT, issued by the dashboard's session-exchange flow. Tokens are short-lived and scoped to a single merchant. No long-lived API keys.

Rate limit

Per-merchant rate limiting; exceeded requests return HTTP 429. The limit is set generously enough that normal dashboard use never hits it.

Plan gates

Endpoints have a minimum tier. Below the required tier, the API returns HTTP 402 (Payment Required) with this body:

{
  "error": "plan_below_required",
  "requiredTier": "growth",
  "currentTier": "starter"
}

The dashboard catches 402 specifically and renders an Upgrade prompt (see Plan tiers). Other 4xx responses are surfaced as errors.

Endpoint list

EndpointMethodTierNotes
/api/merchants/meGETAllReturns the merchant's plan, configuration, and a features map
/api/splitsGETAllPaginated list of splits with status filtering
/api/splits/:idGETAllDetail view of a single split
/api/splits/:id/etaPATCHGrowth+Update a split's expected ship date; triggers delay-notice email if changed
/api/splits/:id/release-holdsPOSTGrowth+Manual hold release (only meaningful when Release preorder holds = manual)
/api/splits-export.csvGETScaleFlat CSV export of all splits, filtered by query params
/api/analytics/preorderGETGrowth+Aggregated metrics plus per-campaign breakdown (Scale-only field)
/api/health/reconciliationGETGrowth+The 4 ops counts (stuck pending, BP missing, dead, stale)
/api/test-emailPOSTGrowth+Send a sample customer notification; rate-limited to 5 per hour
/api/configPOSTAllSave Settings; per-field Scale gates on hold_release_rule='on_deposit_paid' and non-empty campaign_tag_prefix
/api/brightpearl/healthGETAllCheck Brightpearl connectivity plus circuit breaker state
/api/shopify/healthGETAllSame for Shopify

Response shape conventions

  • Successful responses are JSON objects. Lists are wrapped in a { <resource>: [...], hasMore: bool } shape rather than a bare array.
  • Timestamps are ISO 8601 strings with timezone (2026-08-15T00:00:00Z).
  • Money amounts are decimal strings, not numbers, which preserves precision ("49.99", not 49.99).
  • Currencies are ISO 4217 codes.
  • Boolean is JSON true or false. Never 1 or 0.

Public API plans

There's currently no public-merchant REST or GraphQL surface. A merchant who wants recurring exports has to download CSVs by hand.

If you need API access for an integration, email hello@nohold.app and tell us what you'd use it for. Likely on Scale tier when it ships.

On this page