# Quickstart

This walks you from no key to a successful call and a successful write. It takes
about five minutes.

<Steps>
  <Step title="Create a secret key">
    In your dashboard, open **Settings, API keys** and create a key. Grant it only
    what your integration needs. For this walkthrough tick **Read** on Products.

    Your key is shown once, at creation. Copy it then. Mercemur stores only a hash,
    so nobody can recover the value for you later, including support.

    ```bash
    export MERCEMUR_SECRET_KEY="sk_..."
    ```

    <Warning>
      A secret key can read and change your store. Keep it server side. Never put it
      in a browser bundle, a mobile app, or a public repository.
    </Warning>
  </Step>

  <Step title="Make your first read">
    Every request goes to `https://api.mercemur.com/api/v1` and carries the key as a
    bearer token.

    <CodeGroup>

    ```bash curl
    curl https://api.mercemur.com/api/v1/products \
      -H "Authorization: Bearer $MERCEMUR_SECRET_KEY"
    ```

    ```javascript Node.js
    const res = await fetch("https://api.mercemur.com/api/v1/products", {
      headers: { Authorization: `Bearer ${process.env.MERCEMUR_SECRET_KEY}` },
    })
    const body = await res.json()
    console.log(body.data)
    ```

    ```python Python
    import os, requests

    res = requests.get(
        "https://api.mercemur.com/api/v1/products",
        headers={"Authorization": f"Bearer {os.environ['MERCEMUR_SECRET_KEY']}"},
    )
    print(res.json()["data"])
    ```

    ```go Go
    req, _ := http.NewRequest("GET", "https://api.mercemur.com/api/v1/products", nil)
    req.Header.Set("Authorization", "Bearer "+os.Getenv("MERCEMUR_SECRET_KEY"))
    res, err := http.DefaultClient.Do(req)
    ```

    ```php PHP
    $ch = curl_init("https://api.mercemur.com/api/v1/products");
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer " . getenv("MERCEMUR_SECRET_KEY"),
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $body = json_decode(curl_exec($ch), true);
    ```

    </CodeGroup>

    A successful list response has your records in `data` and paging state in `page`:

    ```json
    {
      "data": [
        { "id": "prod_01J...", "title": "Merino crew", "status": "published" }
      ],
      "page": {
        "has_more": true,
        "next_cursor": "eyJ2IjoxLCJrIjoi..."
      }
    }
    ```
  </Step>

  <Step title="Handle the refusal you are most likely to hit first">
    If the key lacks the scope for the route, you get `403` and the message names the
    exact scope to tick:

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

    Add the scope in the dashboard and retry. Scope changes apply to the existing key,
    so you do not need to issue a new one. See [Scopes](/authentication/scopes).
  </Step>

  <Step title="Make your first write">
    Writes need one extra header: a unique `Idempotency-Key`. It is required, not
    optional, and it is what makes a retry safe after a timeout.

    ```bash
    curl -X POST https://api.mercemur.com/api/v1/products \
      -H "Authorization: Bearer $MERCEMUR_SECRET_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{
            "title": "Merino crew",
            "status": "draft"
          }'
    ```

    Generate a fresh key per logical operation, and reuse that same key when you retry
    that operation. Replaying it returns the original response instead of creating a
    second product. See [Idempotency](/requests/idempotency).

    <Note>
      This write needs `write_products`. Read and write are separate grants, so a key
      with only Read will be refused here.
    </Note>
  </Step>

  <Step title="Page through a full collection">
    There is no `page` or `offset`. You pass the previous response's
    `page.next_cursor` back as `after`, and stop when `has_more` is false.

    ```bash
    curl "https://api.mercemur.com/api/v1/products?limit=100&after=eyJ2IjoxLCJrIjoi..." \
      -H "Authorization: Bearer $MERCEMUR_SECRET_KEY"
    ```

    See [Pagination](/requests/pagination).
  </Step>
</Steps>

## Next

<Columns cols={2}>
  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Every endpoint, with a playground bound to your own store.
  </Card>
  <Card title="Money" icon="money-bill" href="/requests/money">
    Read this before you send an amount. Every value is an integer in minor units.
  </Card>
</Columns>
