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

# Getting Started

> One showUnify() call to let users buy a domain or connect one they own, in 5 minutes.

Welcome to Entri! This guide walks you through your first integration: a single `showUnify()` call that lets your users connect a domain they already own or buy a new one, without you building a selection screen or managing two flows.

<Tip>
  New to DNS? Check out [DNS Concepts](/dns-concepts) for a quick primer on record types, propagation, and common gotchas.
</Tip>

## 1. Set up your dashboard

Before writing code, configure your application in the [Entri Dashboard](https://dashboard.entri.com):

1. Sign up or log in
2. Create an application
3. Set your display name and icon (PNG or SVG, 1:1 ratio, white or transparent background)
4. Copy your `applicationId` and `secret`

<img src="https://mintcdn.com/entri-42/06YvuUaP9BrTKHMC/images/dashboard.png?fit=max&auto=format&n=06YvuUaP9BrTKHMC&q=85&s=8e93a839ec4ad1ba41fab903d452b5c0" alt="Dashboard" width="1397" height="1062" data-path="images/dashboard.png" />

## 2. Install Entri

Choose your preferred installation method:

<CodeGroup>
  ```html HTML (CDN) theme={null}
  <script src="https://cdn.goentri.com/entri.js"></script>
  ```

  ```bash npm theme={null}
  npm install entrijs
  ```
</CodeGroup>

If using npm, import it in your code:

```javascript theme={null}
import Entri from 'entrijs';
```

<Note>
  **Subresource Integrity (SRI):** If your security policy requires SRI, load Entri via the pinned loader URL with its SHA-384 hash:

  ```html theme={null}
  <script
    src="https://cdn.goentri.com/entri-latest.js"
    integrity="sha384-wnpzG3Yw9ogy4KIE2XZ/Cn9/fqwjb53eR5Te9a3cjud6UZF5wbmQrfWFKfBwZfaI"
    crossorigin="anonymous"></script>
  ```

  The loader at `entri-latest.js` is immutable, so the integrity hash above stays valid across Entri SDK releases — no need to update it on each version.

  Because the loader fetches the SDK asynchronously, `window.entri` isn't available immediately. Wait for the `entri:ready` event before calling `showUnify()`:

  <CodeGroup>
    ```javascript Callback theme={null}
    function onEntriReady(cb) {
      if (window.entri) return cb(window.entri);
      window.addEventListener("entri:ready", () => cb(window.entri), { once: true });
    }

    onEntriReady((entri) => {
      entri.showUnify(/* …config… */);
    });
    ```

    ```javascript Promise theme={null}
    const entriReady = new Promise((resolve) => {
      if (window.entri) return resolve(window.entri);
      window.addEventListener("entri:ready", () => resolve(window.entri), { once: true });
    });

    entriReady.then((entri) => entri.showUnify(/* …config… */));
    ```
  </CodeGroup>
</Note>

## 3. Get a JWT token

For security, fetch the JWT on your **server-side**. The token expires after 60 minutes.

<Warning>
  Never expose your `secret` in client-side code. Always fetch the JWT from your backend.
</Warning>

<CodeGroup>
  ```javascript JavaScript theme={null}
  fetch('https://api.goentri.com/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      applicationId: "YOUR_APP_ID",    // From the dashboard
      secret: "YOUR_SECRET"            // From the dashboard
    }),
  })
  .then(response => response.json())
  .then(data => {
    console.log('Token:', data.auth_token);
    // Save this token to use in step 4
  })
  .catch(error => console.error('Error:', error));
  ```

  ```python Python theme={null}
  import requests
  import json

  url = "https://api.goentri.com/token"
  payload = {
      "applicationId": "YOUR_APP_ID",  # From the dashboard
      "secret": "YOUR_SECRET"          # From the dashboard
  }
  headers = {"Content-Type": "application/json"}

  response = requests.post(url, headers=headers, data=json.dumps(payload))
  if response.ok:
      data = response.json()
      print("Token:", data["auth_token"])
      # Save this token to use in step 4
  else:
      print("Error:", response.text)
  ```
</CodeGroup>

## 4. Launch the Entri modal

With your token ready, launch the Entri modal. Entri asks the user whether they want to buy a new domain or connect one they already own, then routes them through the right flow. The records you pass in `dnsRecords` are applied either way; this example uses a single CNAME, and [DNS Records](/connect/dns-records) covers all supported types and their fields:

```javascript theme={null}
entri.showUnify({
  applicationId: "YOUR_APP_ID",
  token: "YOUR_JWT_TOKEN",  // From step 3
  dnsRecords: [
    {
      type: "CNAME",
      host: "www",
      value: "your-app.com",
      ttl: 300
    }
  ]
});
```

That's the whole integration. No selection UI to build, no branching logic, no separate purchase and connect code paths.

<Check>
  **DNS monitoring is included.** Every domain added through `showUnify()` is automatically enrolled in [Entri Monitor](/monitor/overview), which watches its DNS records and notifies your webhook if they change or break. No extra configuration needed.
</Check>

<Info>
  If you only need one of the two paths, call [`connectDomain()`](/connect/sdk#entri-connectdomain-config) (connect an existing domain) or [`purchaseDomain()`](/sell/sdk) (buy a new one) directly. They take the same config, but note that they don't enroll domains in Entri Monitor by default; pass `monitor: true` if you want monitoring. `connectDomain()` was previously named `showEntri()`, which is deprecated but still works as an alias.
</Info>

## 5. Handle events

Listen for completion and close events:

```javascript theme={null}
entri.showUnify({
  applicationId: "YOUR_APP_ID",
  token: "YOUR_JWT_TOKEN",
  dnsRecords: [...],

  // Called when DNS setup completes successfully
  onSuccess: (data) => {
    console.log('Domain configured:', data.domain);
    // { domain: "example.com", success: true, setupType: "automatic", ... }
  },

  // Called when the modal is closed
  onEntriClose: (data) => {
    console.log('Modal closed:', data);
  }
});
```

If you want to know which path the user chose, listen for the `onEntriPathSelected` browser event. After that, the selected flow fires its regular events. See [Unify events](/unify/events) for the details.

```javascript theme={null}
window.addEventListener('onEntriPathSelected', (event) => {
  console.log('User chose:', event.detail.path); // "sell" or "connect"
});
```

## Complete example: React

Here's a full working example with React:

```jsx theme={null}
import { useEffect, useState } from 'react';

function DomainSetup() {
  const [token, setToken] = useState(null);

  useEffect(() => {
    // Fetch JWT from your backend
    fetch('/api/entri-token')
      .then(res => res.json())
      .then(data => setToken(data.token));
  }, []);

  const handleSetup = () => {
    if (!token) return;

    entri.showUnify({
      applicationId: "YOUR_APP_ID",
      token: token,
      dnsRecords: [
        {
          type: "CNAME",
          host: "www",
          value: "your-app.com",
          ttl: 300
        }
      ],
      onSuccess: (data) => {
        console.log('Success:', data);
        // Update your UI or backend
      }
    });
  };

  return (
    <button onClick={handleSetup} disabled={!token}>
      Add Your Domain
    </button>
  );
}

export default DomainSetup;
```

<Note>
  For more framework-specific examples, see our [React Integration Guide](/integration/react) and [Vanilla JS Guide](/integration/vanilla-js).
</Note>

## Next steps

You just integrated [Entri Unify](/unify/overview), which routes your users into Entri Connect (existing domains) or Entri Sell (new purchases) behind a single call. Explore those flows and the rest of Entri's products:

<CardGroup cols={2}>
  <Card title="Connect" icon="wifi" iconType="duotone" href="/connect/overview">
    Automated DNS configuration for 60+ providers
  </Card>

  <Card title="Sell" icon="browser" iconType="duotone" href="/sell/overview">
    Let users purchase domains in your app
  </Card>

  <Card title="Secure" icon="lock" iconType="duotone" href="/secure/overview">
    Automatic SSL certificate provisioning
  </Card>

  <Card title="Power" icon="bolt" iconType="duotone" href="/power/overview">
    Custom domain management for your users
  </Card>
</CardGroup>

## Dive deeper

<CardGroup cols={2}>
  <Card title="Configuration Reference" icon="gear" href="/unify/configuration">
    All showUnify() options
  </Card>

  <Card title="Events Reference" icon="bell" href="/unify/events">
    Complete events documentation
  </Card>

  <Card title="Webhooks" icon="webhook" href="/webhooks-overview">
    Server-side notifications
  </Card>

  <Card title="DNS Concepts" icon="server" href="/dns-concepts">
    Understanding DNS records
  </Card>
</CardGroup>

## Need help?

We're here to help! Email us at [support@entri.com](mailto:support@entri.com) or reach out to your account manager.
