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.
Add and edit products
Once a user is verified (Bootstrap) and you hold theirmk_user_* key, you can add and edit products on any storefront they own. Both endpoints require scope catalog:write and honor Idempotency-Key (see Safe mutations).
Add a product
POST /v1/storefronts/{storefrontId}/products — returns 201 Created with the full product DTO.
Response — 201 Created
imageProcessingPending: true means Marea will sweep the source URL into its own CDN asynchronously; imageUrl continues to serve from the source until then.
Required + optional fields
| Field | Type | Required | Notes |
|---|---|---|---|
title | string (1–200) | yes | |
price | number (≥ 0) | yes | Storefront currency. |
description | string | no | |
salePrice | number (≥ 0) | no | If set + below price, shown crossed-out. |
category / subcategory | string | no | |
imageUrl / thumbnailUrl | URL | no | Both swept into Marea CDN async (BL-CAT-10). |
sku / slug | string | no | |
position | int | no | Defaults to last + 1. |
cartProduct / hide | boolean | no | |
stock | int | no | Surfaced on the storefront as inventory remaining. |
tags | string[] | no | |
extraProductsCategory | object[] | no | Modifier groups (size, toppings). See OpenAPI schema. |
Update a product
PATCH /v1/storefronts/{storefrontId}/products/{productId} — returns 200 OK with the full updated ProductDto. Every field is PATCHable (no immutable fields).
null (e.g. { "imageUrl": null }). Omitting a field leaves it untouched.
Idempotency
SameIdempotency-Key + same body within 24 hours → original response replayed (no duplicate writes). Same key + different body → 409 idempotency_conflict. See Safe mutations.
If your batch importer hits a transient network error mid-flight, retry with the same Idempotency-Key per product — the server is replay-safe.
Plan caps and 402 mid-batch
The single-productPOST endpoint returns 402 plan_limit (plan_max_products_reached) the moment a write would exceed the user’s plan cap. Stop the batch as soon as you see it; surface error.upgrade.upgradeUrl; do not retry until the user upgrades.
Bulk-load alternative: 207 Multi-Status
If you’re seeding a whole catalog at once, usePOST /v1/storefronts with the manifest’s products[] array (or pass initialStorefront.products on POST /v1/users). When the manifest exceeds the plan cap, Marea returns 207 Multi-Status — the storefront is created with products up to the cap and the response errors[] array lists what was skipped:
Other recoverable errors
| HTTP | error.type / code | What happened | Agent action |
|---|---|---|---|
| 400 | invalid_request / invalid_request_body | Body validation (negative price, missing title, malformed field) — see error.param for which field failed | Fix the body, reissue with a NEW Idempotency-Key. |
| 402 | plan_limit / plan_max_products_reached | This single-product write would exceed the plan cap | Surface error.upgrade.upgradeUrl; do not retry until upgrade. |
| 404 | not_found / storefront_not_found | Wrong storefront id, or this user-key doesn’t own it (silent cross-tenant). Product not-found also surfaces here. | Confirm the ids; cannot infer ownership. |
| 409 | idempotency_conflict | Same Idempotency-Key reused with a different body | Generate a fresh UUID for the retry. |
| 429 | rate_limited / rate_limit_exceeded (message contains rpm_exceeded) | Per-user rpm: 60 cap | Sleep Retry-After (seconds), retry with the same key. |
Cross-references
- Storefronts — parent-object model.
- Plan limits — product caps per plan (Free 30, Basic 60, Pro 200, Business 2000+).
- Safe mutations —
Idempotency-Keysemantics.