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

# Authentication

> Authenticate API requests with the project key.

export const CopyPrompt = () => {
  const [copied, setCopied] = useState(false);
  const prompt = "Tell me which Vampauth credential is which: Project ID (public identifier), Project Key pk-... (public API key, authenticates API calls via X-Project-Key, ships inside the client script), Public Signing Key (public, verifies Ed25519 signatures), signing private key (server-only secret that signs responses, never exposed). Also list the rate limits for key/check (120/60s per IP) and hwid/reset (60/60s per IP). Under 8 lines.";
  const copy = async () => {
    try {
      await navigator.clipboard.writeText(prompt);
    } catch {
      const t = document.createElement("textarea");
      t.value = prompt;
      document.body.appendChild(t);
      t.select();
      document.execCommand("copy");
      document.body.removeChild(t);
    }
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };
  return <div className="not-prose my-4 flex items-center justify-between gap-3 rounded-lg border border-zinc-200 px-4 py-2.5 dark:border-zinc-800">
      <span className="text-xs font-semibold uppercase tracking-wider text-zinc-500 dark:text-zinc-400">AI prompt</span>
      <button onClick={copy} className="cursor-pointer rounded border border-zinc-300 px-2.5 py-1 text-xs font-semibold text-zinc-700 hover:bg-zinc-100 dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800">{copied ? "Copied" : "Copy"}</button>
    </div>;
};

# Authentication

All API requests authenticate with the project's key, sent as the `X-Project-Key` header.

```
X-Project-Key: pk-...
```

The dashboard exposes three project values. Know which is which:

| Value                  | Secret? | Where it's used                                               |
| ---------------------- | ------- | ------------------------------------------------------------- |
| Project ID             | No      | Identifying the project in responses and URLs.                |
| Project Key (`pk-...`) | No      | Authenticates API calls. **Embed in the client script.**      |
| Public Signing Key     | No      | Verifies `key/check` signatures. Safe to embed in the client. |
| Signing private key    | **Yes** | Signs `key/check` responses. Server-only, never exposed.      |

## What is and isn't secret

The Project Key is a **public API key**, not a bearer secret. It exists so the API knows which project you are calling. It is designed to ship inside the script — the script cannot call `key/check` without it, so it has to be there.

An attacker who extracts the Project Key from a script gains nothing:

* They still need a valid, unexpired license key whose HWID matches — `key/check` returns an error otherwise.
* The Project Key cannot issue keys, revoke keys, or modify the project.
* It cannot forge responses. Forging requires the signing **private** key.

The one value that must never leak is the **signing private key**. It lives only on the server, signs every `key/check` response, and is not exposed by any endpoint. The Public Signing Key is the only crypto material that ships to the client — the script uses it to verify, never to sign.

## Rate limits

| Endpoint     | Limit                     |
| ------------ | ------------------------- |
| `key/check`  | 120 requests / 60s per IP |
| `hwid/reset` | 60 requests / 60s per IP  |

Exceeding a limit returns `429` with `retry_after`.

<CopyPrompt id="authentication" />
