# Mercemur Docs

Mercemur gives every merchant three doors into the same store: a REST API to call
from code, an MCP server so an AI agent can act on it directly, and a CLI to edit a
storefront as files on your own machine. All three are governed by the same secret
key and the same scopes, one grant, whichever door you use.

## Start here

<Columns cols={3}>
  <Card title="API" icon="code" href="/api-reference/introduction">
    574 operations across catalogue, orders, customers, pricing, and money. Call it
    from any platform that can send an HTTP request.
  </Card>
  <Card title="MCP" icon="sparkles" href="/mcp/overview">
    Point an AI client, Claude Desktop, an IDE, another agent, at one endpoint and it
    can read and write your live storefront.
  </Card>
  <Card title="CLI" icon="terminal" href="/cli/overview">
    Pull your storefront to disk, edit it in your own editor with live preview, and
    publish when you're ready.
  </Card>
</Columns>

<Info>
  REST API base URL for every request: `https://api.mercemur.com/api/v1` &middot; MCP
  endpoint: `https://mcp.mercemur.com/mcp`
</Info>

## The REST API in detail

<Columns cols={3}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Create a key and make your first call in under five minutes.
  </Card>
  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Every endpoint, with a playground you can fire against your own store.
  </Card>
  <Card title="Rate limits" icon="gauge" href="/essentials/rate-limits">
    Understand throttling and how to back off correctly.
  </Card>
</Columns>

## Authentication and security

<Columns cols={3}>
  <Card title="API keys" icon="key" href="/authentication/api-keys">
    Secret keys, how to create them, and how to rotate one safely.
  </Card>
  <Card title="Scopes" icon="lock" href="/authentication/scopes">
    Read, write and delete are separate grants. 154 scopes across 68 families.
  </Card>
  <Card title="Error handling" icon="triangle-exclamation" href="/errors/envelope">
    One envelope for every refusal, at every status.
  </Card>
</Columns>

## Making requests

<Columns cols={3}>
  <Card title="Idempotency" icon="repeat" href="/requests/idempotency">
    Every write takes an `Idempotency-Key`. Retry safely.
  </Card>
  <Card title="Pagination" icon="list" href="/requests/pagination">
    Cursor paging, forward only, signed and bound to the route that issued it.
  </Card>
  <Card title="Money" icon="money-bill" href="/requests/money">
    Every amount is an integer in the currency's minor unit.
  </Card>
</Columns>

## The four things that are not guessable from one endpoint

If you read nothing else, read these. They are the conventions that a single
example request will not teach you, and each one has bitten an integration.

<AccordionGroup>
  <Accordion title="Money is an integer in minor units, never a decimal">
    `1999` in a `usd` field is 19.99 USD. There are no fractional amounts anywhere
    in this API, and no field accepts a decimal. Currencies with no minor unit,
    such as JPY, take the whole number directly. See [Money](/requests/money).
  </Accordion>

  <Accordion title="Read and write are separate grants">
    `write_products` does **not** let a key read your catalogue, and deleting is a
    third grant again: `write_products:delete`. A key that keeps records up to date
    cannot destroy them unless you tick Delete as well. See [Scopes](/authentication/scopes).
  </Accordion>

  <Accordion title="Every write requires an Idempotency-Key">
    Not optional, and not only for retries. A request without the header is refused
    with `idempotency_key_required`. Replaying the same key returns the stored
    response rather than executing twice. See [Idempotency](/requests/idempotency).
  </Accordion>

  <Accordion title="Paging is by cursor, forward only">
    There is no `page` or `offset` parameter. You send `?after=` with the
    `page.next_cursor` from the previous response **for that same endpoint**. A
    cursor from a different collection is refused. See [Pagination](/requests/pagination).
  </Accordion>
</AccordionGroup>

## Branch on `code`, never on `message`

Every refusal on this API, at every status, has the same body:

```json
{
  "error": {
    "code": "insufficient_scope",
    "message": "this api key requires the write_products scope"
  }
}
```

The `code` is the contract and is safe to switch on. The `message` is English prose
for a human reading a log, and its wording is not part of this contract. See
[Error envelope](/errors/envelope).
