---
title: "Connect your SDKs"
description: "Point the Web, Flutter and Node SDKs at a self-hosted endpoint instead of Pug Cloud."
---

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

# Connect your SDKs

By default every Pug SDK sends data to **Pug Cloud** (`https://api.pugs.dev`). When you self-host, you change **one thing**: point the SDK's endpoint at your own `pug server`. Nothing else about the API changes — same methods, same keys, same events.

Use the **public** URL of your server (the TLS-terminated origin in front of port 3000, e.g. `https://api.example.com`), not the internal `:3000` address.

## The one setting, per SDK

It's the same option — `endpoint` — on every SDK (the HTTP API just uses the request URL):

| SDK | Package | Option | Default |
|-----|---------|--------|---------|
| Browser | `@pug-sh/browser` | `endpoint` | `https://api.pugs.dev` |
| Flutter | `pug_flutter` | `endpoint` | `https://api.pugs.dev` |
| Node (server) | `@pug-sh/node` | `endpoint` | `https://api.pugs.dev` |
| HTTP API | — | request URL | `https://api.pugs.dev` |

## Browser

```ts
import { init } from '@pug-sh/browser'

init('YOUR_PROJECT_ID', {
  apiKey: 'pub_YOUR_PUBLIC_KEY',
  endpoint: 'https://api.example.com', // your pug server
})
```

For environment-aware config (e.g. Vite), fall back to localhost in dev:

```ts
init(import.meta.env.VITE_PUG_PROJECT_ID, {
  apiKey: import.meta.env.VITE_PUG_PUBLIC_KEY,
  endpoint: import.meta.env.DEV ? 'http://localhost:3000' : 'https://api.example.com',
})
```

## Flutter

```dart
import 'package:pug_flutter/pug_flutter.dart';

await Pug.init(
  'YOUR_PROJECT_ID',
  const PugOptions(
apiKey: 'pub_your_public_key',
endpoint: 'https://api.example.com', // your pug server
  ),
);
```

## Node (server-side)

The Node SDK takes the same `endpoint` option and authenticates with your **private** key (`prv_…`):

```ts
import { Pug } from '@pug-sh/node'

const pug = new Pug({
  apiKey: process.env.PUG_PRIVATE_KEY!, // prv_… — server-side only
  endpoint: 'https://api.example.com', // your pug server
})
```

## HTTP API

If you call the API directly, just swap the host in the request URL — the paths are unchanged:

```bash
curl https://api.example.com/sdk.events.v1.EventsService/BatchCreate \
  -H "content-type: application/json" \
  -H "x-api-key: pub_YOUR_PUBLIC_KEY" \
  -d '{ "projectId": "YOUR_PROJECT_ID", "events": [ /* … */ ] }'
```

## Notes

- **No SDK-specific CORS setup is needed on the server.** The events and profiles ingest services accept any origin (auth lives entirely in the `x-api-key` header). Only the **dashboard** origin needs listing in `PUG_CORS_ORIGINS` — see [Dashboard](/self-hosting/dashboard).
- **Keys are unchanged.** Public keys (`pub_…`) for the browser/Flutter SDKs, private keys (`prv_…`) for the Node SDK and server-to-server reads. See [Authentication](/get-started/authentication).
- **Verify it works:** open your self-hosted dashboard's **Live** view — an event fired from a repointed SDK should appear within ~15 seconds. If requests fail with a network error, confirm the endpoint is your public HTTPS origin and that TLS terminates in front of the server.

For the full initialization options (batching, sessions, auto-capture, consent), see the [SDKs](/sdks) reference.

## Further reading

- [Dashboard](/self-hosting/dashboard) — the dashboard's own `VITE_API_BASE_URL` endpoint setting
- [Deployment](/self-hosting/deployment) — stand up the server your SDKs point at
- [Development](/self-hosting/development) — point SDKs at a local `pug dev`

Source: https://docs.pug.sh/self-hosting/connect-sdks/index.mdx
