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

# Authentication

> Sign Public API requests with YoLead HMAC headers.

All `/v1/*` requests require these headers:

```http theme={null}
X-YoLead-Key: <publicKey>
X-YoLead-Timestamp: <unix_ms_timestamp>
X-YoLead-Signature: <hex_hmac_sha256>
```

Create the signature with HMAC-SHA256 over:

```txt theme={null}
<timestamp>.<raw_body>
```

For requests without a body, `raw_body` is empty. The timestamp must be within a 5-minute window.

<Tip>
  For `POST` and `PATCH` requests, sign the exact raw JSON string that you send as the request body. Do not parse and re-serialize JSON between signing and sending the request.
</Tip>

<CodeGroup>
  ```ts Node.js theme={null}
  import { createHmac } from "node:crypto";

  function signYoLeadRequest(apiSecret: string, timestamp: string, rawBody: string) {
    return createHmac("sha256", apiSecret)
      .update(`${timestamp}.`)
      .update(rawBody)
      .digest("hex");
  }
  ```

  ```php PHP theme={null}
  <?php

  function signYoLeadRequest(string $apiSecret, string $timestamp, string $rawBody): string
  {
      return hash_hmac('sha256', $timestamp . '.' . $rawBody, $apiSecret);
  }
  ```
</CodeGroup>

## Signing a JSON body

<CodeGroup>
  ```ts Node.js theme={null}
  const publicKey = process.env.YOLEAD_PUBLIC_KEY!;
  const apiSecret = process.env.YOLEAD_SECRET!;
  const timestamp = Date.now().toString();

  const payload = {
    employeeId: "64f000000000000000000001",
    chatId: "64f000000000000000000002",
    capabilities: ["showChatPage"],
  };

  const rawBody = JSON.stringify(payload);
  const signature = signYoLeadRequest(apiSecret, timestamp, rawBody);

  const response = await fetch("https://api.yo-lead.com/v1/embed/sessions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-YoLead-Key": publicKey,
      "X-YoLead-Timestamp": timestamp,
      "X-YoLead-Signature": signature,
    },
    body: rawBody,
  });

  console.log(await response.json());
  ```

  ```php PHP theme={null}
  <?php

  $publicKey = getenv('YOLEAD_PUBLIC_KEY');
  $apiSecret = getenv('YOLEAD_SECRET');
  $timestamp = (string) round(microtime(true) * 1000);

  $payload = [
      'employeeId' => '64f000000000000000000001',
      'chatId' => '64f000000000000000000002',
      'capabilities' => ['showChatPage'],
  ];

  $rawBody = json_encode($payload, JSON_UNESCAPED_SLASHES);
  $signature = signYoLeadRequest($apiSecret, $timestamp, $rawBody);

  $ch = curl_init('https://api.yo-lead.com/v1/embed/sessions');

  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_POSTFIELDS => $rawBody,
      CURLOPT_HTTPHEADER => [
          'Content-Type: application/json',
          'X-YoLead-Key: ' . $publicKey,
          'X-YoLead-Timestamp: ' . $timestamp,
          'X-YoLead-Signature: ' . $signature,
      ],
  ]);

  $body = curl_exec($ch);
  $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

  if ($body === false) {
      throw new RuntimeException(curl_error($ch));
  }

  curl_close($ch);

  echo $status . PHP_EOL;
  echo $body . PHP_EOL;
  ```
</CodeGroup>
