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

# Authentication

> Learn how to authenticate API requests to Genuka securely and handle possible authentication errors.

Proper authentication is essential to secure your Genuka integration. This guide explains how to authenticate your API requests, outlines error scenarios, and presents best practices.
We have several ways to authenticate our requests. We can either use the `API Key` or the `token` that we must add to the header.
In the following, we will present both methods.

> ⚠️ **Important — Verify the HMAC before any authentication**
>
> Before performing any authentication or token exchange, your application **must verify the HMAC signature** sent by Genuka in the installation callback.
>
> This step ensures the request **truly comes from Genuka** and prevents malicious third-party access.
>
> 👉 [Learn how to verify the HMAC →](/hmac-verification)

***

## Using API Key authentication

Genuka uses API keys to authenticate requests.\
However, **API Key authentication is reserved exclusively for Genuka clients** who wish to connect their stores or perform actions directly from their own company account.

⚠️ **Developers building external applications** should **not** use this method — their integrations are authenticated **via Access Tokens** instead (see the next section).

### How it works

1. You can find these in your **Genuka Dashboard → Settings → API Keys**.
2. Generate a new key and copy it.

### Example request

```bash theme={null}
curl -X GET "https://preprod-api.genuka.com/2023-11/orders" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Company: YOUR_COMPANY_ID" \
  -H "X-Shop: YOUR_SHOP_ID"
```

## Authentication with Access Token

Besides API keys, you can authenticate requests using an **Access Token**.\
This method is used for applications installed by a company via the Genuka platform. When a company installs your app, Genuka sends a **callback** with information such as `company_id`, `code`, `timestamp`, `hmac`, and `redirect_to`.

### How it works

1. When your application is installed by a company, it receives a callback from Genuka containing `company_id`, `code`, `timestamp`, `hmac`, and `redirect_to`.
2. Your application should use its `GENUKA_CLIENT_ID`, `GENUKA_CLIENT_SECRET`, `GENUKA_REDIRECT_URI` along with the endpoint `https://api.genuka.com/oauth/token` to **exchange the code for an access token**.
3. Store the company as a user in your database.
4. **Keep the access token private** to ensure secure API requests on behalf of that company.
5. Include the token in the `Authorization` header for all subsequent requests.

### Example: Using the Access Token

<CodeGroup>
  ```javascript fetch theme={null}

  const params = new URLSearchParams({
    grant_type: "authorization_code",
    code: "CODE_FROM_CALLBACK",
    client_id: process.env.GENUKA_CLIENT_ID,
    client_secret: process.env.GENUKA_CLIENT_SECRET,
    redirect_uri: process.env.GENUKA_REDIRECT_URI,
  });

  const tokenResponse = await fetch("https://api.genuka.com/oauth/2023-11/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: params,
  });

  const { access_token } = await tokenResponse.json();

  // Use access_token to get orders
  const ordersResponse = await fetch("https://api.genuka.com/orders", {
    headers: { Authorization: `Bearer ${access_token}` },
  });

  const orders = await ordersResponse.json();
  console.log(orders);
  ```

  ```javascript genuka-api SDK theme={null}
  import Genuka from "genuka-api";

  const genuka = await Genuka.initialize({ adminMode: true });
  genuka.setCompanyId("COMPANY_ID_FROM_CALLBACK");
  genuka.setToken("ACCESS_TOKEN_FROM_TOKEN_EXCHANGE");

  const orders = await genuka.orders.list({ isAdmin: true });
  console.log(orders);
  ```

  ```javascript React theme={null}
  import { useEffect } from "react";

  function OrdersComponent() {
    const access_token = "ACCESS_TOKEN_FROM_TOKEN_EXCHANGE";

    useEffect(() => {
      async function fetchOrders() {
        const res = await fetch("https://api.genuka.com/orders", {
          headers: { Authorization: `Bearer ${access_token}` },
        });
        const orders = await res.json();
        console.log(orders);
      }
      fetchOrders();
    }, []);

    return <div>Check console for orders</div>;
  }
  ```
</CodeGroup>

## Common Authentication Errors

If authentication fails, Genuka returns clear error messages:

| Error Scenario           | HTTP Code | Message                                                                | Likely Cause                             |
| ------------------------ | --------- | ---------------------------------------------------------------------- | ---------------------------------------- |
| Missing API Key          | 401       | `"code": 401, "message": "API key is missing"`                         | Authorization header not provided        |
| Invalid or Revoked Key   | 401       | `"code": 401, "message": "Invalid API key"`                            | Wrong or expired API key                 |
| Unauthorized Live Access | 403       | `"code": 403, "message": "Sandbox key not allowed for live operation"` | Using sandbox key for production request |
