Changelog
REST v1: stricter validation, working upgrade link, WhatsApp number frozen on PATCH
Changed: validation and pagination on the REST API, plus one behavior change.
PATCH /v1/storefronts/{storefrontId}rejectswhatsapp. The order number is set at creation and changed in the dashboard. A patch that includes it, even asnull, returns400 invalid_requestand writes nothing.marea.update_storefronton the MCP no longer accepts it either.- The
402upgrade link works.error.upgrade.upgradeUrlopens the plan screen in the dashboard with the monthly Basic plan preselected. It used to point at a route that did not exist. - Stricter input rules.
currencymust be an ISO 4217 code andbusinessTypeone of the dashboard values (both listed in the OpenAPI spec).whatsappmust be E.164 at creation.salePricemust be belowprice,stockcannot be negative, delivery ranges cannot overlap, and image URLs must behttp(s). Text fields refuse HTML tags and inline handlers; ordinary text with=or<is fine. - Cursors are opaque and id-ordered.
nextCursoris now based on the document id, so pages no longer skip items that share a timestamp. Cursors from before this change are ignored and the list restarts at page one. GET /v1/mereturnsscopesand, when the account cannot publish,_links.upgradeUrl. The MCP server usesscopesto list only the tools a static key can call.- OpenAPI is machine-consumable. Every operation has an
operationId, parameters and request bodies.openapi.jsonand the Postman collection are re-vendored. - Idempotent replays of a failed write return the original error again instead of
200with an empty body.
MCP server 1.1.0: connect from Claude, ChatGPT or Cursor without a key
Added: OAuth 2.1 on the MCP server, and three read tools.Merchants can now connect Marea to an AI client themselves. Add
https://mcp.mareaalcalina.com/mcp as a custom connector in Claude, ChatGPT, Cursor or Claude Code, sign in to Marea, authorize, and the tools are live. No key to paste and no JSON file to edit.- OAuth 2.1 + PKCE, discovered from the
WWW-Authenticatechallenge on a 401 (RFC 9728). Client ID Metadata Documents are the preferred registration path; Dynamic Client Registration at/oauth/registerstill works. Scopes:marea.read,marea.write,marea.publish. - Consent mints a per-user key named after the app, visible and deletable in the dashboard under Desarrolladores, Claves API. Deleting it disconnects the app. Token revocation is at
POST /oauth/revoke(RFC 7009). - Ten tools now. The three new ones are
marea.list_storefronts,marea.get_storefrontandmarea.list_products. Every argument now carries a description, andbusinessTypeuses the dashboard’s own values. - Publish confirmation is the client’s. The in-band elicitation gate and its
_confirmedargument are gone;marea.publish_storefrontis annotateddestructiveHint: trueand clients show their own prompt._idempotencyKeyand_acceptLanguageare unchanged. - Static keys are unchanged.
Authorization: Bearer mk_user_*(own account) ormk_dev_*(partners that bootstrap accounts) stays the path for servers, CI and agents with no browser.marea.bootstrap_userneedsmk_dev_*and is never reachable over OAuth.
Self-serve user keys from the dashboard
Added — One-click
mk_user_* issuance for verified users.Verified users can now mint and list their own mk_user_* keys directly from the dashboard at mareaalcalina.com/developers/keys — no partner bootstrap required. Keys issued this way start with the full post-verify scope set (catalog read/write, storefront publish), so you can drive the API against your own storefronts in a single click.What this means for you:- No more “you must be bootstrapped by a partner” path for solo builders. Sign up, verify, then issue a key.
- Multiple keys per user. Mint one per environment or per integration; list and revoke them from the same page.
- The raw key is shown once. Copy it on issuance — only the SHA-256 hash is stored server-side.
PRD-14 — Stripe-style webhook endpoints (model unification)
Added — Webhook endpoints as first-class objects.Stripe-style endpoint model: each endpoint owns its URL, its
subscribedEvents[] list, and its own 64-char-hex signingSecret. Up to 16 endpoints per account.- REST CRUD:
POST /v1/webhook_endpoints,GET /v1/webhook_endpoints,GET /v1/webhook_endpoints/:id,POST /v1/webhook_endpoints/:id(update),DELETE /v1/webhook_endpoints/:id. Required scope:developer:webhooks(new keys) ordeveloper:bootstrap(existing keys continue to work via any-of). - Order events on developer endpoints: a single developer endpoint receives
order.*events from every storefront your key bootstrapped — no per-merchant endpoint registration needed. - Signing: HMAC-SHA256 with the endpoint’s raw 64-char-hex
signingSecretfor every event type. - Envelope carries
eventId(UUID v4 — receiver dedup key) +apiVersion: 2026-05-12. Headers:X-Marea-Endpoint-Id,X-Marea-Signing-Version. - Dashboard at
/developers/webhooksmanages endpoints (create / edit / pause / rotate / delete / test fire / view recent deliveries). - Phase B (deferred): the same multi-endpoint model will roll out for merchant-configured page webhooks in a follow-up release.
Docs site accuracy + DX overhaul
Improved — comprehensive docs audit + Stripe-style cleanup.Following the first public publish, a senior-engineer pass cross-checked every claim in the docs against the cloud-functions Zod contracts as ground truth.
- API Reference now covers all 13 v1 operations (previously a Phase-1 stub with
/v1/meonly).openapi.jsonis script-generated from the cloud-functions Zod schemas via@asteasolutions/zod-to-openapi(zero drift): tags, operationIds, both security schemes (Bearer + X-API-Key), rate-limit response headers, idempotency headers, and full$reftoApiErrorResponseon every 4xx/5xx. - Stripe-style URL slugs. API reference pages now ship at clean URLs like
/api/storefronts/create-storefrontand/api/identity/get-current-identity(previously they were verbose auto-slugified sentences). - Plan limits corrected.
plan.limitsshape is{storefronts, products, publishable}(not the docs’ previous{maxStorefronts, maxProducts, canPublish}invention). Free plan has two variants (FREE_NEW1 storefront,FREE_OLDlegacy 3 storefronts). Pre-paywall accounts have a 2,000 draft-product cap. Single-product POST returnsplan_max_products_reached, notproducts_over_limit(the latter is the 207-batch path). - Scopes corrected. Eight real scopes:
developer:bootstrap,developer:read,developer:issueUserKey,catalog:read,catalog:write,storefront:publish,me:verify,me:resendVerification. Earlier docs referenced a non-existentusers:bootstrap— now removed everywhere. - Error codes: ~40 real
error.codevalues cross-checked againstgrep ApiErroracrosssrc/api/. Removed fabricated codes (validation_failed,product_not_found,invalid_request_body,rpd_exceeded-as-code) that the docs invented; replaced with the real ones (invalid_request,storefront_not_found,rate_limit_exceeded).rpd_exceeded/rpm_exceededcontinue to surface insideerror.messageonly. - MCP quickstart: install path now uses the
mcp-remotebridge (verified package). Tool count corrected to 7 (verify + resend are REST-only by design). - Four concept pages that were placeholders are now real content:
verification-flow,tos-jurisdiction,arco-procedures,versioning. Each is sourced from cloud-functions handlers, with TTLs, lockouts, cancel reasons, and breaking-change rules from code. - Homepage: removed redundant H1 + intro paragraph that duplicated frontmatter title/description (Mintlify renders both automatically). Added a “Webhook surfaces” CardGroup so first-time readers see both surfaces.
- Receiver helpers:
concepts/webhooksnow ships full JS + Python verifiers inapi/webhooks/*.mdx, with theX-Marea-Source(developervsmerchant) header disambiguating event sources.