Quickstart
Run Pulse
Section titled “Run Pulse”Pulse now ships as one app: pulse-server serves both the API and the dashboard.
1) Install the binary
Section titled “1) Install the binary”curl -fsSL https://raw.githubusercontent.com/EK-LABS-LLC/trace-service/main/scripts/install.sh | bash -s -- pulse-serverThis installs both pulse-server (trace service) and pulse (CLI integrations).
To upgrade an existing local install, run the same command again. It replaces the binaries and dashboard assets in place and preserves your existing ~/.pulse data, including stored traces.
2) Choose your workflow
Section titled “2) Choose your workflow”Local managed Pulse
Section titled “Local managed Pulse”Use this when you want one local command path and a background server managed by the CLI.
pulse setup --localpulse upThen verify:
pulse statusDaily use after the first setup:
pulse uppulse statusOpen the dashboard at http://localhost:3000/ or run:
pulse dashboardRemote/shared Pulse
Section titled “Remote/shared Pulse”Use this when a Pulse instance already exists at a URL you can reach.
pulse connect \ --api-url https://pulse.example.com \ --api-key pulse_sk_... \ --project-id my-projectThen verify:
pulse statusUpdating
Section titled “Updating”Local/self-hosted Pulse
Section titled “Local/self-hosted Pulse”Re-run the server installer:
curl -fsSL https://raw.githubusercontent.com/EK-LABS-LLC/trace-service/main/scripts/install.sh | bash -s -- pulse-serverThis upgrades:
pulse-server- dashboard assets
pulseCLI
It does not erase ~/.pulse, so local trace data and config are preserved.
Remote/shared-instance users
Section titled “Remote/shared-instance users”If you only need the CLI locally, re-run the CLI installer:
curl -fsSL https://raw.githubusercontent.com/EK-LABS-LLC/trace-cli/main/install.sh | sh3) Advanced self-hosting modes
Section titled “3) Advanced self-hosting modes”If you are operating pulse-server directly, choose single for local SQLite or scale for Postgres-backed higher-throughput ingest.
See Single vs Scale Modes for the full environment and deployment guidance.
Single mode example:
export PULSE_MODE=singleexport BETTER_AUTH_SECRET="$(openssl rand -hex 32)"export ENCRYPTION_KEY="$(openssl rand -hex 32)"export BETTER_AUTH_URL='http://localhost:3000'Scale mode example:
export PULSE_MODE=scaleexport DATABASE_URL='postgresql://pulse:pulse@localhost:5432/pulse'export BETTER_AUTH_SECRET="$(openssl rand -hex 32)"export ENCRYPTION_KEY="$(openssl rand -hex 32)"export BETTER_AUTH_URL='http://localhost:3000'Install SDK
Section titled “Install SDK”bun add @eklabs/pulse-sdkpip install pulse-trace-sdkWorks with Bun, Node, or any JavaScript/Python runtime.
CLI integrations (Claude Code, Opencode, OpenClaw)
Section titled “CLI integrations (Claude Code, Opencode, OpenClaw)”If you want Pulse to capture coding-agent events in addition to SDK traces:
# Local managed Pulsepulse setup --localpulse up
# Or connect to a shared Pulse instance:# pulse connect --api-url https://pulse.example.com --api-key pulse_sk_... --project-id my-project
# Verify config, connectivity, and integration statuspulse statusSee CLI Reference for full command and config details.
Initialize
Section titled “Initialize”Call initPulse() once at application startup using the API key created during pulse setup or pulse connect.
import { initPulse } from "@eklabs/pulse-sdk";
initPulse({ apiKey: "pulse_sk_...",});from pulse_sdk import init_pulse
init_pulse({ "api_key": "pulse_sk_...",})This starts background trace batches and registers shutdown handlers to flush remaining traces on exit.
Wrap your client
Section titled “Wrap your client”Use observe() to wrap your LLM client. The returned client behaves identically and tracing is captured as a side effect.
import { initPulse, observe, Provider } from "@eklabs/pulse-sdk";import OpenAI from "openai";
initPulse({ apiKey: "pulse_sk_..." });
const client = observe( new OpenAI({ apiKey: "sk-..." }), Provider.OpenAI);
const res = await client.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: "Hello" }],});from pulse_sdk import init_pulse, observe, Providerfrom openai import OpenAI
init_pulse({ "api_key": "pulse_sk_..." })
client = observe( OpenAI(api_key="sk-..."), Provider.OPENAI)
res = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Hello"}],)What gets captured
Section titled “What gets captured”| Field | Description |
|---|---|
| Request and response bodies | Full prompt and completion |
| Token counts | Input and output tokens |
| Latency | End-to-end request duration in milliseconds |
| Cost | Provider-reported or SDK-estimated when model pricing is available |
| Model | Requested and actual model used |
| Status | success or error |
| Provider | openai, anthropic, or openrouter |
Supported providers
Section titled “Supported providers”| Provider | Client | Enum |
|---|---|---|
| OpenAI | openai | Provider.OpenAI |
| Anthropic | @anthropic-ai/sdk | Provider.Anthropic |
| OpenRouter | openai | Provider.OpenRouter |
See Providers for detailed usage.