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

# Quickstart

> Install the Heretic collector, collect one browser session, and retrieve its settled projection from your server.

This guide connects one browser collection to one server-side verdict read.

You need two active keys for the same site:

* A public site key such as `hrtc_live_0123456789abcdef01234567`. Put it in browser code. It attributes a settled projection to the site, but it does not sign collection or authorize reads.
* A secret verdict key such as `hrtc_sk_0123456789abcdef0123456789abcdef`. Keep it on your server. It reads projected verdicts attributed to that site.

<Warning>
  Never place an `hrtc_sk_...` key in browser code, a public environment variable, or a client bundle.
</Warning>

<Steps titleSize="h2">
  <Step title="Install the collector">
    ```bash theme={null}
    npm install @heretic-hq/collector
    ```
  </Step>

  <Step title="Collect in the browser">
    ```js theme={null}
    import { heretic } from '@heretic-hq/collector';

    const result = await heretic({
      siteKey: 'hrtc_live_0123456789abcdef01234567',
    });

    if (!result.ok || !result.requestId) {
      console.warn('Heretic collection did not complete', result.reason);
    } else {
      await fetch('/api/heretic-request', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ requestId: result.requestId }),
      });
    }
    ```

    `heretic()` resolves rather than rejecting into the host page:

    ```ts theme={null}
    type HereticResult = {
      ok: boolean;
      requestId?: string | null;
      reason?: string;
    };
    ```

    The function starts one run per page. Later calls reuse the first run and its configuration.
  </Step>

  <Step title="Read the projection from your server">
    ```js theme={null}
    const VERDICT_ORIGIN = 'https://heretic.tech';

    export async function readHereticVerdict(requestId) {
      const response = await fetch(
        `${VERDICT_ORIGIN}/v1/verdict/${encodeURIComponent(requestId)}`,
        {
          headers: {
            authorization: `Bearer ${process.env.HERETIC_VERDICT_KEY}`,
          },
        },
      );

      if (response.status === 200) {
        return { state: 'available', value: await response.json() };
      }

      if (response.status === 404) {
        return { state: 'unavailable' };
      }

      if (response.status === 401) {
        throw new Error(
          'Heretic verdict key is missing, malformed, unknown, or revoked',
        );
      }

      throw new Error(`Heretic verdict read failed with HTTP ${response.status}`);
    }
    ```

    Configure the key only in your server environment:

    ```bash theme={null}
    HERETIC_VERDICT_KEY=hrtc_sk_0123456789abcdef0123456789abcdef
    ```
  </Step>

  <Step title="Use immediate readiness">
    Successful ordinary collection returns a raw 32-character lowercase hexadecimal request ID after D1 acknowledges the tenant-visible projection. Your server can retrieve that ID immediately. Do not add a fixed polling delay.

    Missing, invalid, foreign, deleted, archived, pruned, and ZDR IDs share `404`.
  </Step>

  <Step title="Use structured fields">
    ```js theme={null}
    const read = await readHereticVerdict(requestId);

    if (read.state === 'available') {
      const { verdict, conclusive, families, provenance } = read.value;
      console.log({ verdict, conclusive, families, provenance });
    }
    ```

    Read [Verdicts and coverage](/concepts/verdicts-and-coverage) before interpreting the values. Do not parse human-readable prose fields.
  </Step>
</Steps>

<Columns cols={2}>
  <Card title="Collector reference" href="/integration/collector">
    Review every public option, endpoint resolution, CSP behavior, and ZDR.
  </Card>

  <Card title="Tenant verdict endpoint" href="/api/verdict-endpoint">
    Review authentication, status codes, timing, and response limits.
  </Card>
</Columns>


## Related topics

- [Heretic documentation](/index.md)
