Getting Started
Get up and running with Pingerchips in minutes.
What is Pingerchips?
Pingerchips is real-time infrastructure for AI applications. It gives your agents and users a shared, live connection — so LLM streams reach the browser instantly, agent state is visible as it changes, and multiple agents can coordinate without polling.
Core primitives:
| Primitive | What it does |
|---|---|
| Channels | Fast pub/sub — public, private, and presence |
| Durable Objects | Named, persistent key-value entities with real-time subscriptions |
| Chat / Sessions | Durable threads with LLM token streaming and message history |
| Spaces | Ephemeral presence — cursors, members, locations, and locks |
| Pingerflows | Visual pipeline to filter, transform, throttle, and route events |
1. Create an App
- Sign up or log in at dashboard.pingerchips.com
- Go to Dashboard → Apps → New App
- Give it a name and click Create
You will see three credentials on the app settings page:
| Credential | Use |
|---|---|
| App ID | Internal identifier |
| App Key | Public — pass to the client SDK to connect |
| App Secret | Private — authenticates server requests and mints capability tokens. Never expose in frontend code |
Store them as environment variables:
PINGERCHIPS_APP_KEY=your-app-key
PINGERCHIPS_APP_SECRET=your-app-secret2. Install the SDKs
npm install pingerchips-js pingerchips-js-serverpingerchips-js runs in the browser; pingerchips-js-server runs on your
backend. Both are ESM only ("type": "module" or .mjs).
3. Choose your primitive
Channels — fast pub/sub
Send events between your server and clients. Use this when you don't need persistence.
Server:
import PingerchipsServer from 'pingerchips-js-server';
const pc = new PingerchipsServer(
process.env.PINGERCHIPS_APP_KEY,
process.env.PINGERCHIPS_APP_SECRET
);
await pc.trigger('my-channel', 'my-event', { message: 'Hello!' });Client:
import Pingerchips from 'pingerchips-js';
const client = new Pingerchips(process.env.PINGERCHIPS_APP_KEY);
const channel = await client.subscribe('my-channel');
channel.bind('my-event', (data) => {
console.log('Received:', data);
});Durable Objects — persistent agent state
Named objects with slots, atomic operations, and real-time subscriptions. Every write is logged and streamed to all subscribers. Use this for agent run state, shared working memory, and approval queues.
Server — write state:
import PingerchipsServer from 'pingerchips-js-server';
const pc = new PingerchipsServer(
process.env.PINGERCHIPS_APP_KEY,
process.env.PINGERCHIPS_APP_SECRET
);
const run = pc.object('run', 'run-abc123');
await run.set('status', 'processing');
await run.set('model', 'claude-sonnet-5');
await run.append('steps', { tool: 'web_search', at: Date.now() });
await run.increment('token_count', 512);Client — subscribe to changes:
import Pingerchips from 'pingerchips-js';
const pc = new Pingerchips('YOUR_APP_KEY', { authEndpoint: '/auth/durable' });
const run = await pc.object('run', 'run-abc123');
console.log(run.state);
// { status: "processing", model: "claude-sonnet-5", token_count: 512, steps: [...] }
run.on('change:status', ({ value }) => updateStatusBadge(value));Add the auth endpoint with pc.authenticateObject(...) from
pingerchips-js-server — see the
Durable Objects quickstart.
Chat / Sessions — LLM streaming with persistence
Durable threads where agents stream tokens and messages are stored. Use this for AI chat interfaces, copilots, and multi-agent pipelines that need an audit log.
Client — connect and receive:
import { PingerchipsChat } from 'pingerchips-js/chat';
const chat = new PingerchipsChat('YOUR_APP_KEY', {
authEndpoint: '/chat/auth', // your route → mints a capability token via POST /api/auth
});
const session = await chat.connect('thread-uuid', { clientId: 'user-123' });
const { view } = session;
view.on('update', () => {
paint(view.getMessages());
for (const run of view.runs()) {
if (run.status === 'active') stream(run.runId, view.getStream(run.runId));
}
});
await view.send('Hello!');Agent — stream a response:
import { AgentSession } from 'pingerchips-js-server/agent-session.js';
import Anthropic from '@anthropic-ai/sdk';
// called from your invocation route with { threadId, runId } from the body
export async function onInvocation({ threadId, runId, userText }) {
const agent = new AgentSession(
process.env.PINGERCHIPS_APP_KEY,
process.env.PINGERCHIPS_APP_SECRET,
);
const thread = await agent.connect(threadId, 'my-bot');
const run = thread.createRun(runId);
await run.start();
let text = '';
const stream = new Anthropic().messages.stream(
{ model: 'claude-sonnet-5', max_tokens: 1024, messages: [{ role: 'user', content: userText }] },
{ signal: run.abortSignal },
);
stream.on('text', async (delta) => {
text += delta;
await run.write(text); // full string so far
});
await stream.finalMessage();
await run.write(text);
await run.end('complete');
thread.close();
}See the Chat quickstart for the auth endpoint and history loading.
Spaces — ephemeral presence
Show who's online, share cursors, and coordinate locks. State is fully ephemeral — disconnecting cleans everything up automatically.
import { PingerchipsSpaces } from 'pingerchips-js/spaces';
const spaces = new PingerchipsSpaces('YOUR_APP_KEY');
await spaces.connect();
const space = await spaces.get('doc-abc123', {
clientId: 'user-42',
profile: { name: 'Alice', color: '#FF0099' },
});
space.members.subscribe('enter', (member) => addMember(member));
space.members.subscribe('leave', (member) => removeMember(member));
space.cursors.set({ x: 124, y: 88 });
space.cursors.subscribe('update', ({ member, position }) => {
renderCursor(member.clientId, position);
});See the Spaces quickstart.
Next Steps
- Channels — public, private, and presence channel types
- Durable Objects — persistent state for agents
- Chat / Sessions — LLM streaming and conversation threads
- Spaces — real-time presence and cursors
- Pingerflows — filter, transform, and route events visually
- App Settings — rate limits, credentials, toggles