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
| Endpoint | Method | Tier | Notes |
|---|---|---|---|
/api/merchants/me | GET | All | Returns the merchant's plan, configuration, and a features map |
/api/splits | GET | All | Paginated list of splits with status filtering |
/api/splits/:id | GET | All | Detail view of a single split |
/api/splits/:id/eta | PATCH | Growth+ | Update a split's expected ship date; triggers delay-notice email if changed |
/api/splits/:id/release-holds | POST | Growth+ | Manual hold release (only meaningful when Release preorder holds = manual) |
/api/splits-export.csv | GET | Scale | Flat CSV export of all splits, filtered by query params |
/api/analytics/preorder | GET | Growth+ | Aggregated metrics plus per-campaign breakdown (Scale-only field) |
/api/health/reconciliation | GET | Growth+ | The 4 ops counts (stuck pending, BP missing, dead, stale) |
/api/test-email | POST | Growth+ | Send a sample customer notification; rate-limited to 5 per hour |
/api/config | POST | All | Save Settings; per-field Scale gates on hold_release_rule='on_deposit_paid' and non-empty campaign_tag_prefix |
/api/brightpearl/health | GET | All | Check Brightpearl connectivity plus circuit breaker state |
/api/shopify/health | GET | All | Same 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", not49.99). - Currencies are ISO 4217 codes.
- Boolean is JSON
trueorfalse. Never1or0.
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.