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
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:
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
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_…):
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:
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-keyheader). Only the dashboard origin needs listing inPUG_CORS_ORIGINS— see 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. - 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 reference.
Further reading
- Dashboard — the dashboard’s own
VITE_API_BASE_URLendpoint setting - Deployment — stand up the server your SDKs point at
- Development — point SDKs at a local
pug dev