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

# Quickstart — Web SDK

> Get a clickwrap agreement running in your web app in under 5 minutes.

<Note>
  **Latest SDK versions:** Web `2.3.0` · Android `2.2.0` · React Native `0.3.0` — [View changelog](/dev/resources/changelog)
</Note>

This guide walks you through displaying a clickwrap agreement to your users and verifying their consent on your backend. For a detailed overview of how the pieces fit together, see the [Integration flow](/dev/guides/integration-flow).

## Prerequisites

Before you start, make sure you have:

1. A [ClickTerm account](https://app.clickterm.com/auth/registration)
2. A **published template** with an effective version (see [Product Guide](/product/getting-started/first-clickwrap))
3. An **integration** with your App ID and App Key (from [Integrations](https://app.clickterm.com/integrations))

<Info>
  Need to set up your credentials and template first? See [Creating an app & template](/dev/guides/creating-app-and-template).
</Info>

## 1. Install the SDK

<Tabs>
  <Tab title="npm">
    ```sh theme={null}
    npm install @clickterm/widget
    ```

    ```javascript theme={null}
    import { ClicktermClient, ClicktermDialog } from "@clickterm/widget";
    ```
  </Tab>

  <Tab title="Script tag">
    ```html theme={null}
    <script src="https://unpkg.com/@clickterm/widget"></script>
    <!-- or <script src="https://cdn.jsdelivr.net/npm/@clickterm/widget"></script> -->
    ```

    The script exposes the SDK on the `window.Clickterm` global.
  </Tab>
</Tabs>

For more details, see [Web SDK Installation](/dev/sdk/web/installation).

## 2. Initialize the SDK

Initialize the client with your **App ID**. You can obtain it from the [Integrations](https://app.clickterm.com/integrations) menu in the ClickTerm dashboard. The snippets below use the `window.Clickterm` global — if you installed from npm, use the import from step 1 instead.

```javascript theme={null}
const { ClicktermClient, ClicktermDialog } = window.Clickterm;
ClicktermClient.initialize("YOUR_CLICKTERM_APP_ID");
```

<Warning>
  Never expose your **App Key** in client-side code. The App Key is used
  only for backend verification calls. The client SDK uses only the **App ID**.
  Store the App Key safely — it won't display again after creation, but can be
  regenerated. Regenerating the key requires updating your backend configuration.
</Warning>

<Warning>
  Without initialization the SDK will not work and you will get an error when trying to request a clickwrap.
</Warning>

## 3. Show the clickwrap dialog

Call `ClicktermDialog.show()` to present the clickwrap to your user. The SDK:

1. Fetches the current effective template version from ClickTerm
2. Displays it in a modal dialog
3. Creates an event in ClickTerm once the end user accepts or declines
4. Returns a **Signature** to your application

The event remains unverified until your backend calls the verification endpoint.

```javascript example.js theme={null}
ClicktermDialog.show({
  endUserId: "user-123",                // Your identifier for the end user
  clickwrapTemplateId: "YOUR_TEMPLATE_ID", // From the ClickTerm dashboard
  language: "en"                         // Optional — falls back to default language
}).then((result) => {
  if (result.clicktermSignature) {
    // Send Signature to your backend for verification
    sendToBackend(result.clicktermSignature);
  } else if (result.isAlreadyAccepted) {
    // User already accepted the latest major version — no dialog was shown
  }
}).catch((error) => {
  console.error("Clickwrap error:", error);
});
```

The dialog only appears if the user hasn't already accepted the latest major version. Requests to show a clickwrap are **not** counted toward billing.

For the full list of parameters, result fields, and configuration options, see [Displaying a clickwrap](/dev/guides/displaying-clickwrap).

## 4. Verify on your backend

After the end user accepts or declines the clickwrap, the SDK creates an unverified event in ClickTerm and returns a Signature. Send this Signature to your server, then call ClickTerm's verification endpoint with your **App ID** and **App Key**. This verifies the event — confirming the Signature hasn't been forged or tampered with. For accepted events, a **Certificate of Acceptance** is generated.

```bash theme={null}
curl -X POST https://api.clickterm.com/public-client/v1/clickwrap/verify \
  -H "X-APP-ID: YOUR_APP_ID" \
  -H "X-APP-KEY: YOUR_APP_KEY" \
  -H "Content-Type: application/json" \
  -d '{"clicktermSignature": "SIGNATURE_FROM_SDK"}'
```

The response contains `clickwrapEventStatus` (`"ACCEPTED"` or `"DECLINED"`) along with the full event metadata (event ID, template version, timestamps, etc.).

* **`ACCEPTED`** — The user accepted the terms. The event is now verified and a Certificate of Acceptance is generated.
* **`DECLINED`** — The event is still verified, but no Certificate of Acceptance is generated. It's up to your application to decide how to handle this (e.g., block the user journey or restrict features).

<Warning>
  Requests to `/clickwrap/verify` **are counted toward billing**. Implement rate
  limiting or a Captcha check before this step to prevent abuse.
</Warning>

For full request/response details and framework-specific examples (Node.js, Python, Java), see [Verifying a Signature](/dev/guides/verifying-signature).

## 5. Alternative: Inline clickwrap

If you prefer to embed a consent checkbox directly in your page instead of showing a modal, use `ClicktermDom.renderInline()` (SDK v2.2.0+):

```html theme={null}
<div id="my-consent"></div>
```

```javascript theme={null}
const { ClicktermClient, ClicktermDom } = window.Clickterm;
ClicktermClient.initialize("YOUR_CLICKTERM_APP_ID");

const handle = await ClicktermDom.renderInline(
  "my-consent",
  {
    endUserId: "user-123",
    clickwrapTemplateId: "YOUR_TEMPLATE_ID",
  },
  {
    onChange: (checked) => {
      document.getElementById("submit-btn").disabled = !checked;
    },
  }
);

// Finalize when the user submits your form
const result = await handle.finalize();
// Send result.clicktermSignature to your backend for verification
```

Inline mode is ideal for registration forms, checkouts, and multi-consent flows. For the full guide, see [Displaying an inline clickwrap](/dev/guides/displaying-inline-clickwrap).

## Next steps

<CardGroup cols={2}>
  <Card title="Integration flow" icon="diagram-project" iconType="light" href="/dev/guides/integration-flow">
    Understand the complete integration architecture.
  </Card>

  <Card title="Template placeholders" icon="brackets-curly" iconType="light" href="/dev/guides/placeholders">
    Pass user-specific data into your clickwrap templates.
  </Card>

  <Card title="Widget customization" icon="palette" iconType="light" href="/dev/guides/widget-customization">
    Customize the dialog appearance from the dashboard.
  </Card>

  <Card title="API Reference" icon="square-terminal" iconType="light" href="/api-reference/overview">
    Explore all available API endpoints.
  </Card>
</CardGroup>
