# Quickstart

Send your first card in a few minutes. The fastest path is an **SDK**: install it, copy one
setup file, then report errors with a single call.

## 1. Create an API key

1. Open your project → **Settings → API Keys**.
2. Click **Create key** and choose a type:
    - **Publishable** (`bb_pub_…`) for browsers and mobile apps — sent as a bearer token.
    - **Secret** (`bb_sec_…`) for servers — used to sign requests; never transmitted.
3. Copy the value(s) immediately. BugBoard stores only a hash and can't show them again.

See **[Choosing a key type](/docs/installation/choosing-a-key)** if you're not sure which to pick.

## 2. Install the SDK

Pick your language:

<!-- tabs:JavaScript,PHP -->

```bash
npm i bugboard
```

```bash
composer require bugboard/sdk
```

## 3. Add the setup file

Create one file that configures a shared client. Set your key in the environment first.

<!-- tabs:JavaScript,PHP -->

```ts
// utils/bugboard.ts
import { createClient } from 'bugboard';

export default createClient({
    apiKey: import.meta.env.VITE_BUGBOARD_API_KEY,
});
```

```php
// app/Services/BugBoard.php
namespace App\Services;

use BugBoard\Client;
use BugBoard\ClientBuilder;
use BugBoard\Config;

class BugBoard
{
    public static function __callStatic(string $method, array $args): void
    {
        once(fn (): Client => ClientBuilder::create(new Config(
            keyId: env('BUGBOARD_KEY_ID'),
            signingSecret: env('BUGBOARD_SIGNING_SECRET'),
        )))->{$method}(...$args);
    }
}
```

## 4. Report your first error

<!-- tabs:JavaScript,PHP -->

```ts
import bugboard from '@/utils/bugboard';

bugboard.critical('My first BugBoard card');
```

```php
use App\Services\BugBoard;

BugBoard::critical('My first BugBoard card');
```

Open your project board — the card is there. Report the same title again and BugBoard
**deduplicates** it: instead of a second card, the existing one's `occurrence_count` is bumped.

The reports don't have to be identical. Matching on the **title _or_ the description** is enough,
so a stable title with a per-event description still groups onto one card — and each distinct
payload is kept beneath it as a **variant**, with its own count and last-seen time. Put the details
that change every time (ids, amounts, stack traces) in the description, and keep the title stable.
Full rules in **[Deduplication](/docs/api-reference#deduplication-important-for-sdk-design)**.

For everything the SDK can do — priority variants, sampling, payload encryption — open your
language guide in **[Install an SDK](/docs/installation/install)**.

## Prefer raw HTTP?

You don't need an SDK. Any language can `POST` to the API directly — only `severity` is required:

```bash
curl -i -X POST "https://bugboard.dev/api/v1/tasks" \
  -H "Authorization: Bearer $BUGBOARD_PUBLISHABLE_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"severity":"major","title":"My first BugBoard card"}'
```

A first `POST` returns **`201 Created`**; an identical second `POST` returns **`200 OK`** with
`"deduplicated": true`. Servers should use a **secret** key and sign each request — the full
signing algorithm and every payload field live in the **[API Reference](/docs/api-reference)**.

This example gets the created card back in `data`, which is what you want for a smoke test. The
SDKs instead send `X-Bb-Hide-Response` by default, so the server withholds the card and returns
only the outcome flags — a report you encrypted should never come back in plaintext.

## Next steps

- **[Authentication](/docs/authentication/overview)** — keys, signing, and origin allow-lists in depth.
- **[Error Codes](/docs/error-codes)** — what each response status means.
- **[Rate Limits & Quotas](/docs/rate-limits)** — burst limits and monthly caps.
