# Getting Started



## Installation [#installation]

Add the OptinStack script tag to your page. It loads the consent runtime, which fetches your project configuration and renders the banner automatically:

```html
<script
  src="https://api.optinstack.com/v1/js/runtime/stable/optinstack.js"
  data-optinstack-site="{projectId}"
></script>
```

Replace `{projectId}` with your project ID from the OptinStack dashboard. Place the tag as the first element inside `<head>`, before any third-party scripts.

## How it works [#how-it-works]

When the script loads, the runtime:

1. Loads the consent runtime bundle and fetches your published project configuration using the `data-optinstack-site` attribute
2. Detects the visitor's region and matches the appropriate consent rule
3. Checks for existing consent stored in the browser
4. Renders the consent banner inside a Shadow DOM (isolated from your page styles)
5. Blocks known third-party scripts and iframes from your published tracker inventory, plus resources you manually tag with consent categories
6. Records consent updates so they are available in OptinStack reporting

The runtime resolves configuration for the current hostname only when that hostname has Free, paid, Enterprise, or Workspace coverage. For production, use the public hostname visitors see. Webflow and Framer development hostnames can carry Free or paid coverage while you build; Free can also activate on the verified production hostname, and paid plans include one self-service move. See [Domain Scans](/domain-scans) for hostname, reverse-proxy, and scanner access guidance.

## Using the API [#using-the-api]

Wait for initialization before calling API methods:

```js
await window.OptinStack.ready;

console.log(window.OptinStack.version);
console.log(window.OptinStack.choices);
```

If your code runs in a module or after the script tag, `await OptinStack.ready` is sufficient. For inline scripts that may run before the bundle finishes loading, defer your logic:

```js
(async () => {
  await window.OptinStack.ready;
  window.OptinStack.events.on('consent-updated', (detail) => {
    console.log('Consent changed:', detail.choices);
  });
})();
```

See the [JavaScript API](/api) reference for the full surface.

## Consent categories [#consent-categories]

OptinStack uses four fixed consent categories:

| Category      | Default        | Description                            |
| ------------- | -------------- | -------------------------------------- |
| `necessary`   | Always `true`  | Essential trackers, cannot be declined |
| `analytics`   | Varies by mode | Analytics and performance tracking     |
| `marketing`   | Varies by mode | Advertising and marketing trackers     |
| `preferences` | Varies by mode | Functionality and personalization      |

<Callout type="warn">
  The `necessary` category is always `true` and cannot be set to `false`. This is enforced at every level of the SDK.
</Callout>

## Consent model vs banner variant [#consent-model-vs-banner-variant]

Two related values describe the matched regional policy:

| Property                | Values                                            | Meaning                                                       |
| ----------------------- | ------------------------------------------------- | ------------------------------------------------------------- |
| `mode` (`consentModel`) | `opt-in`, `opt-out`, `informational`              | How optional categories default and what counts as a decision |
| `uiVariant`             | `opt-in`, `opt-out`, `informational`, `dont-sell` | Which banner UI the visitor sees                              |

| Model / variant                  | Behavior                                                                          |
| -------------------------------- | --------------------------------------------------------------------------------- |
| `opt-in`                         | Optional categories default to `false`. The visitor must explicitly accept.       |
| `opt-out`                        | Optional categories default to `true`. The visitor can reject.                    |
| `informational`                  | Banner acknowledges notice and records accept-all consent.                        |
| `dont-sell` (**uiVariant** only) | Banner uses "Do Not Sell or Share" style copy; the underlying model is `opt-out`. |

```js
await window.OptinStack.ready;
console.log(window.OptinStack.mode); // consent model
console.log(window.OptinStack.uiVariant); // banner UI
```

## Languages [#languages]

English is the fixed source language. Free and Pro publish English only. On Business and Enterprise, you can enable secondary locales (22 languages beyond English, including major EU, APAC, and MENA languages). The runtime loads published packs from the CDN using the page `html lang` (normalized to a primary subtag such as `fr` from `fr-CA`). Languages you have not enabled fall back to English. Translations update when you publish configuration; they do not require reinstalling the script.

If you need a language that is not listed yet, [contact us](https://optinstack.com/contact) and we will review adding it.

See banner language settings in the [dashboard](https://app.optinstack.com).

## Global Privacy Control [#global-privacy-control]

When the browser sends a [Global Privacy Control](https://globalprivacycontrol.org/) signal (`navigator.globalPrivacyControl === true`), the runtime records `gpc: true`. By default, all optional category defaults become `false`. On plans with advanced GPC controls, you can configure which optional categories GPC rejects.

```js
await window.OptinStack.ready;

if (window.OptinStack.gpc) {
  console.log('GPC signal detected, optional categories defaulted to false');
}
```

GPC is also reflected in consent records and in the GTM dataLayer event `optinstack_gpc_signal_detected`. See [Google Consent Mode](/consent-mode).

## Next steps [#next-steps]

<Cards>
  <Card title="Install" href="/install">
    Add the runtime script and place it before third-party trackers.
  </Card>

  <Card title="Domain scans" href="/domain-scans">
    Choose the right public hostname for scans, staging previews, and reverse proxies.
  </Card>

  <Card title="JavaScript API" href="/api">
    Read and write consent state, subscribe to changes, and use UI helpers.
  </Card>

  <Card title="Consent cookie" href="/consent-cookie">
    Read stored consent state and understand subdomain sharing.
  </Card>

  <Card title="Banner control" href="/banner-control">
    Open preferences, reset consent, and build custom consent flows.
  </Card>

  <Card title="Events" href="/events">
    Subscribe to consent, blocking, and reporting events.
  </Card>
</Cards>
