Bootstrap a user account
This is the partner / agent flow. Use it when you’re building an AI agent, vertical SaaS, or agency tool that creates Marea accounts for other people. If you already own a Marea storefront and just want API access to it, you don’t need this — grab your
mk_user_* from your dashboard and skip straight to Add products.Step 1 — Create the user
$MAREA_USER_KEY. You only reach back for $MAREA_DEV_KEY when bootstrapping another user, listing your users, or managing webhook endpoints.
Required body fields
| Field | Required | Notes |
|---|---|---|
email | yes | Where the 6-digit code is sent. |
displayName | yes | Shown in the dashboard + on the storefront. |
sourceAgent | yes | Your agent identifier — e.g. claude-desktop. Logged on the user. |
country / language / currency / businessType | no | Inferred from Accept-Language if omitted; reported back in appliedDefaults. |
initialStorefront | no | Full StorefrontManifest if you want products in the same call. |
Partial-success (207)
IfinitialStorefront.products[] exceeds the user’s plan cap, Marea returns 207 with the storefront created up to the cap and an errors[] array describing what was skipped. Surface those verbatim and prompt for upgrade. See Plan limits.
Step 2 — Verify the 6-digit code
The user gets a code in their inbox. Either ask them to read it aloud, or read it via the Gmail MCP — see Verification flow.$MAREA_USER_KEY is now upgraded in place — it gains catalog:read, catalog:write, storefront:publish on top of the verify scopes it already had. Do not rotate or re-issue. You can now call any product or storefront endpoint.
If the code is wrong / expired / never arrived
Two keys, one mental model
You only see two API keys in the whole API:$MAREA_DEV_KEY— your agent’s own key, issued from /developers/keys. Used to bootstrap users and manage webhook endpoints. Never grants catalog access.$MAREA_USER_KEY— a single user’s key, returned byPOST /v1/users. Used for everything you do on behalf of that user (catalog reads, product writes, publish) across every storefront the user owns. One key per user, not one key per storefront. Tenant boundary is baked into the key — it can only see/edit that user’s data.
403 insufficient_scope, you’re sending the wrong key. The error response includes requiredScopes[] and heldScopes[] so you can tell at a glance which one was needed.
Full model + rotation rules: /concepts/keys.
Errors you should branch on
Every non-2xx follows the §9.6 envelope:{ type, code, message, doc, param, requestId, requestLogUrl, recoverable, retryAfterMs, nextActions[], upgrade }. Branch on error.type and error.code — never on error.message (localized).
Step 1 — POST /v1/users
| HTTP | error.code | What happened | Agent action |
|---|---|---|---|
| 400 | invalid_request | Email malformed, missing field, etc. | Fix the body, reissue with a NEW Idempotency-Key. |
| 401 | missing_authorization / invalid_authorization_format / key_not_found / key_revoked | Bad/missing/revoked dev key | Re-prompt for a valid mk_dev_*. |
| 403 | insufficient_scope | Dev key lacks developer:bootstrap | Issue a key with the right scope (see requiredScopes in body). |
| 409 | email_exists | The email already has a Marea account | Send the user to log in. |
| 429 | rate_limit_exceeded (message contains rpd_exceeded) | Dev-key daily cap hit (50/day default) | Sleep retryAfterMs, then retry. |
Full error response examples (auth, conflict, rate-limit)
Full error response examples (auth, conflict, rate-limit)
Step 2 — POST /v1/users/:userId/verify
| HTTP | error.code | What happened | Agent action |
|---|---|---|---|
| 400 | code_invalid | Wrong digits | Ask the user to re-read — up to 3 attempts before lockout. |
| 404 | code_not_found | No active code (already verified or never sent) | Call resend, then retry. |
| 404 | user_not_found | :userId doesn’t match the calling key | Wrong $MAREA_USER_KEY for this $USER_ID. |
| 410 | code_expired | 15-minute TTL elapsed | Call resend, then retry. |
| 429 | too_many_attempts | 3 failed attempts on the same code | Call resend (issues a new code), then retry. |
Next steps
- Add and edit products — use
$MAREA_USER_KEYfrom here on. - Publish a storefront — handle the 402 paywall, 422 empty, and 451 ToS gates.
- Install MCP in Claude Desktop / Cursor / Continue.dev — same flow, exposed as
marea.*tools.