> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mutasib.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authenticate with the Mutasib API: API Tokens

> Mutasib uses API tokens for all API access. Generate one from your dashboard and pass it as an Authorization: Bearer header on every request.

Mutasib secures every API request with an **API token**. Generate a token from your [Mutasib dashboard](https://mutasib.com/dashboard), pick an expiration of 30, 60, or 90 days, and attach it to every request as an `Authorization: Bearer` header. All programmatic access to the API uses API tokens.

<Note>
  API tokens are not available on a free trial. An active paid plan is required to create and use them.
</Note>

## Getting a token

1. Sign in to your [Mutasib dashboard](https://mutasib.com/dashboard).
2. Open the API tokens section.
3. Create a new token, choose an expiration of **30, 60, or 90 days**, and copy the token immediately. Tokens are shown only once at creation time.
4. Store the token in a secure secret store (encrypted keystore, environment variable, or secrets manager).
5. Revoke a token anytime from the same section of the dashboard. Once a token expires or is revoked, requests using it return `401 Unauthorized`.

## Using your token

Pass the token in the `Authorization` header on every request. The value must be prefixed with `Bearer ` (note the space).

```text theme={null}
Authorization: Bearer YOUR_API_TOKEN
```

### Example

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.mutasib.com/api/v1/shops/42 \
    -H "Authorization: Bearer YOUR_API_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.mutasib.com/api/v1/shops/42",
      headers={"Authorization": "Bearer YOUR_API_TOKEN"},
  )
  print(response.json())
  ```

  ```js JavaScript theme={null}
  const response = await fetch("https://api.mutasib.com/api/v1/shops/42", {
    headers: { Authorization: "Bearer YOUR_API_TOKEN" },
  });
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

## Scope (allowlist)

API tokens are restricted to a fixed set of path prefixes. Requests to any path outside this list return `404 Not Found`.

| Prefix                          | What's accessible                                                                        |
| ------------------------------- | ---------------------------------------------------------------------------------------- |
| `/api/v1/shops/`                | Shop read/update, products, categories, sales, inventory, and suppliers scoped to a shop |
| `/api/v1/shops/{id}/ai/predict` | AI demand prediction (Pro plan only)                                                     |
| `/api/v1/shops/{id}/ai/reorder` | AI reorder suggestions (Pro plan only)                                                   |
| `/api/v1/products/`             | OpenFood Facts barcode lookup, search, and category browsing                             |
| `/api/v1/credit-notes/`         | Shop credit notes                                                                        |
| `/api/v1/public/`               | Public shop and product search, nearby shops, and receipts                               |

Everything else returns `404 Not Found`. All other `/ai/*` sub-paths are outside the API scope.

## Plan gating

Some features are available only on specific plans. If your token belongs to a shop that doesn't include a feature (for example, an AI endpoint on a Starter plan), the API returns `403 Forbidden` with a `detail` message explaining the required plan. The same gating applies inside the Mutasib dashboard, so a user who cannot reach a feature there also cannot reach it through the API.

Pro-only features currently include AI demand prediction, AI reorder suggestions, supplier management, and credit notes. Inspect the `plan_features` object on the shop response to detect available capabilities at runtime.

## HTTP error codes

When authentication fails, the API returns a standard HTTP error code. The table below lists the codes you will encounter most often and what to do about each.

| Code  | Name                 | Meaning                                                                                           | What to do                                                                                                                                                       |
| ----- | -------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401` | Unauthorized         | No token was provided, the token is invalid, expired, or has been revoked.                        | Include a valid `Authorization: Bearer` header with an active API token. Generate a new token from the dashboard if the current one has expired or been revoked. |
| `403` | Forbidden            | The request was authenticated, but the token does not have permission to perform this action.     | Verify that the account owning the token has the required permissions for the endpoint you are calling.                                                          |
| `404` | Not Found            | The path is outside the API token scope (see the allowlist above) or the resource does not exist. | Check that you are calling one of the allowed prefixes and that the resource ID is correct.                                                                      |
| `422` | Unprocessable Entity | The request was well-formed but failed server-side validation.                                    | Read the `detail` array in the response body. Each entry identifies the field and the reason for rejection.                                                      |

<Tip>
  Treat your API token like a password. Store it in a secure, persistent location such as an encrypted keystore, environment variable, or secrets manager. Never embed tokens in URLs, log files, or client-side source code. If you suspect a token has been compromised, revoke it from the dashboard and generate a new one.
</Tip>
