Documentation Index
Fetch the complete documentation index at: https://docs.mareaalcalina.com/llms.txt
Use this file to discover all available pages before exploring further.
Publishing
POST /v1/storefronts/:storefrontId/publish takes a draft storefront live. It is the only operation that exposes the storefront to the public internet — every other catalog mutation only changes the draft.
Required scope: storefront:publish (held by user keys after verification; not held by developer keys, not held by restricted pre-verify user keys).
Behavior
The handler enforces the following gates in this order:| Order | Gate | On failure |
|---|---|---|
| 1 | Plan paywall | 402 plan_blocks_publish if plan == NO_ACTIVO (pre-paywall state). FREE / BASIC / PRO / BUSINESS all OK. |
| 2 | Ownership pre-check | 404 storefront_not_found (leak-less) if the storefront isn’t owned by the caller’s user |
| 3 | Empty-storefront guard | 422 no_products if the storefront has zero products |
| 4 | ToS gate | 451 tos_not_accepted (reserved — see ToS jurisdiction) |
| 5 | Auto-version | If versionId is omitted, a fresh version snapshot is created atomically |
| 6 | Publish transaction | Marks the version published; idempotent on republish of the same version (200 + same DTO) |
Request
{ "versionId": "ver_xxx" } to publish a specific named version; omit for auto-version (the common case).
Include Idempotency-Key if you want the call to be safe to retry — see Safe mutations.
Successful response (200)
_links.publicUrl is now non-null and stable. Surface it to the user.
Republishing
Calling publish a second time on the same storefront:- If the version already published matches the request, the call is idempotent: the same 200 + DTO is returned.
- If a new version is created (auto-version with new content), a fresh public snapshot is generated.
Error responses
402 plan_blocks_publish — pre-paywall account
NO_ACTIVO (pre-paywall) state hits this. Free, Basic, Pro, and Business all publish successfully. Surface upgrade.upgradeUrl as a CTA. Do not retry until the user upgrades.
422 no_products — empty storefront
Idempotency-Key.
451 tos_not_accepted — user hasn’t accepted ToS
nextActions[0].url verbatim. Once accepted, retry publish with the same Idempotency-Key. See ToS jurisdiction.
404 — storefront not found OR cross-tenant access
If yourmk_user_* key doesn’t own the storefront, you get 404 storefront_not_found (silent denial — not 403). See Storefronts.
What NOT to do
- Don’t auto-publish. Publishing is destructive and user-visible — once it’s live, the URL is shared and may be indexed. Always require explicit user confirmation.
- Don’t retry 402 / 422 / 451 without surfacing
nextActions[]to the user. Each is arecoverable: trueerror that needs user input, not a backoff. - Don’t auto-accept the ToS. The 451 → modal flow is counsel-reviewed and intentional.
Verification in code
src/api/v1/storefronts.publish.ts— the handler with the locked step order.src/utils/publish.utils.ts—runPublishTransaction.src/models/plan-limits.ts—isPublishable()(the 402 gate condition).