# Choosing a key type

BugBoard has **two kinds of API key**, and which one you use depends entirely
on **where your code runs**. A project can hold many named keys, and each is
individually revocable — revoking one never affects the others.

| Where your code runs    | Key type        | Prefix    | How it authenticates                              |
| ----------------------- | --------------- | --------- | ------------------------------------------------- |
| Browser JS, mobile apps | **Publishable** | `bb_pub_` | Bearer token (+ optional origin allow-list)       |
| Node / PHP / any server | **Secret**      | `bb_sec_` | HMAC request signature (the secret is never sent) |

> A secret key **cannot** be used as a bearer token, and a publishable key is
> **not** accepted on the signed path. Use the scheme that matches the key type.

## Publishable keys — client-side

Use a publishable key anywhere the credential is shipped to end users and
**cannot be kept secret**: a single-page app, a mobile binary, a browser
extension.

- **Public by design** and **write-only** — it can only `POST` tasks to its one
  project, so a leak can't read or exfiltrate anything.
- Contained by an optional **origin allow-list** and the project's monthly
  **quota** — those, not secrecy, are what limit abuse.

```yaml
Authorization: Bearer bb_pub_<48 hex chars>
```

## Secret keys — server-side

Use a secret key whenever the credential never reaches an end user: an API
server, a worker, a backend job. **The secret never travels on the wire** —
each request is HMAC-signed instead.

A secret key is issued as two values:

- a **key id** (`bbk_…`) — public; identifies which key signed the request;
- a **signing secret** (`bb_sec_…`) — shown once; used to sign; never transmitted.

## A simple rule

> **Can an attacker read your code or memory and extract the key?**
> If yes (browser, mobile), use a **publishable** key and lock it down.
> If no (your servers), use a **secret** key.

For browser apps that need stronger guarantees, proxy reports through your own
backend (which holds a secret key) instead of embedding a publishable key. See
the server-proxy appendix in the **[JavaScript SDK guide](/docs/sdks/javascript)**.

> **API keys are separate from encryption keys.** A key here proves who is
> reporting; to also keep the report **body** unreadable in transit, add a
> project **encryption key** (a public key safe to embed alongside either API
> key type). See **[Encrypted transport](/docs/security/encryption)**.

Ready to wire it up? Continue to **[Install an SDK](/docs/installation/install)**
or read the **[Authentication](/docs/authentication/overview)** details.
