Want to try it? Pulse is an app for DevQuake members. Create an account or sign in, then try it free for 24 hours or subscribe.

Pulse · User manual

Realtime events for your app

Pulse passes events from one place to many: your server (or a visitor’s browser) sends an event, and every page that listens receives it within a second. You decide what an event carries; Pulse keeps it secure and fair.

1. Getting started

  1. Sign in on devquake.com and open Pulse from your account (try it free for 24 hours, or subscribe).
  2. Create an API service. Copy the secret key straight away: it is shown only once.
  3. Under Your websites, add your site and its DNS record (or turn on Allow localhost to test on your computer).
  4. Open the Live test and send your first event.

2. What people use it for

Anything where a page should change the moment something happens elsewhere, without reloading:

  • Notifications: “Your order has shipped”, “New message”, a badge that counts up.
  • Live dashboards: sales, sign-ups, sensor readings or server status as they happen.
  • Chat and comments: messages that appear for everyone in the room.
  • Scores and games: live results, turns, a scoreboard on a TV and phones at once.
  • Collaboration: a shared list or board where everyone sees the others’ changes.
  • Status of a job: “processing… done” for uploads, payments or exports.
  • Presence: who is online or typing right now.

3. The event format

Every event has the same fixed frame, and inside it your own data as keys and values:

  • channel: where it goes, e.g. orders or room-42. Listeners pick the channels they want.
  • event: what happened, e.g. order.created.
  • data: your keys and values, e.g. orderId: "A-17", total: 42.5, paid: true. Values are text, numbers, yes/no (true/false) or empty (null).
  • Pulse adds id, app (your public key), source (server, web page, client token or live test), sender (from a client token) and at (the time, UTC).

Channels whose name starts with private- can only be used with a client token or the secret key, never with the public key alone.

4. Keys and security

  • Public key (pk_…): goes into your web pages. It only works from your verified websites, can only listen to public channels and, if you allow it, send to them.
  • Secret key (sk_…): stays on your server. It may send to any channel and make client tokens. Pulse refuses it when it comes from a web page, because a secret in a browser is no longer secret.
  • Client tokens: your server makes one for each of your users, valid for up to an hour, listing the channels that user may use and whether they may send. This is the secure way for private channels and for logged-in users.
  • Only you: an API service belongs to your DevQuake account alone. It cannot be shared with other members.
  • Server addresses: optionally allow the secret key only from your servers’ IP addresses.
  • Watching for leaks: Pulse counts the addresses your secret key is used from and logs refused calls. If the key shows up in too many places, you are warned: make a new one (the old one keeps working for 24 hours).

Why a copied key does not help anyone: the public key only works on websites that proved with DNS that they are yours; the secret key is refused in web pages and can be tied to your servers; and every service has limits, so even a stolen key cannot do more than your plan allows.

5. Verifying your website

  1. Under Your websites, enter the address, e.g. https://shop.example.com.
  2. Pulse shows a TXT record: a name like _devquake-pulse.shop.example.com and a value like devquake-pulse=….
  3. Add it where you manage your domain’s DNS (your hosting or domain provider).
  4. Press Check now. After a few minutes (sometimes an hour) the website shows Verified and works.

To test on your own computer, turn on Allow localhost: pages on http://localhost then work without a DNS record. Turn it off when you go live.

6. Your own data structure

Under Your data structure you describe each event you use: its keys, their type (text, number or yes/no) and which are required. For example order.created with orderId (text, required), total (number) and paid (yes/no).

  • Described events are checked: a missing required key or a wrong type is refused with a clear error.
  • Events you did not describe are still accepted, unless you turn on Only described events.
  • With Only described events on, unknown events and unknown keys are refused too: recommended for production.

Keys start with a letter or _ and contain letters, digits and _. At most 20 keys per event; text values up to 500 characters.

7. Live test scenario (5 minutes)

You need: your API service, a computer with a terminal, and a phone (or a second browser window). You do not need a website yet.

  1. Open your API service and press Live test. Keep the channel demo and press Connect: the dot turns green, Live.
  2. Open the same page on your phone (signed in to DevQuake) and press Connect there too.
  3. On the computer, under Send, keep the event hello with the key text = Hello, and press Send event. The phone shows it within a second, with how long it took.
  4. Send from the phone: the computer receives it. Both are listening to demo.
  5. In a terminal, run the curl example from the page with your secret key instead of $PULSE_SECRET_KEY. Both pages receive an event from a server.
  6. Try the rules: add a described event under Your data structure, turn on Only described events and send one with a wrong type: it is refused with the reason.
  7. Try private channels: disconnect, turn on Use a client token, set the channels to private-demo, connect on both devices and send again.

During the free trial events arrive 3 seconds late and connections are shorter: that is on purpose. If a page shows “Connected (polling)”, live connections are blocked on that network; events still arrive, every few seconds.

8. The API in short

  • POST /api/v1/events: send one event. Body: { "channel", "event", "data" }. Authentication: Authorization: Bearer sk_… (server), Authorization: Bearer <client token>, or X-Pulse-Key: pk_… (web page on a verified website). Answers 202 { id, at }.
  • GET /api/v1/stream?key=pk_…&channels=a,b: live events (Server-Sent Events). Use token= instead of key= for a client token. Reconnecting clients catch up from their last event (Last-Event-ID).
  • GET /api/v1/poll?key=…&channels=…&after=<id>: the same events by asking every few seconds, for places where live connections do not work. Answers { events, next, retryAfterMs }.
  • GET /api/v1/client: a small browser library that connects, reconnects, refreshes tokens and falls back to polling by itself.
  • Errors come as { "error": { "code", "message" } } with the HTTP status (401 key, 403 not allowed, 402 no subscription, 429 too many, with Retry-After).

9. Trial, subscription and full access

Pulse runs next to all other DevQuake apps, so every account has fair limits. Your current plan and its numbers are shown on the start page of the app.

  • Free trial (24 hours): 1 API service, 3 live connections, 300 events a day, small events, and events arrive 3 seconds late.
  • Subscribed: 3 API services, 25 live connections and 10,000 events a day each, events at once.
  • Full access: much higher limits for production use. Contact us and tell us what you are building.

When your subscription ends, your API services stop answering (your apps get “subscription required”). When you unsubscribe or delete your account, they are deleted with all their data.

10. Your data

Events are kept only as long as needed for reconnecting clients to catch up (at most a day, a week with full access), usage figures for 35 days and the security log for 30 days. Secret keys are never stored, and addresses only as anonymous hashes. Deleting an API service, unsubscribing or deleting your DevQuake account removes everything.

11. Check it live

Want to see Pulse work before writing any code? The Check it live demo (on the start page of the app) sends events between two of your browsers through the real API.

  1. Open Check it live and press Copy the link.
  2. Open the link in a second browser (another browser, a private window or your phone) and sign in to the same DevQuake account.
  3. Choose A message and type something, or Your own JSON and paste a flat object such as { "order": 42, "paid": true }.
  4. Press Send to my other browser. The other browser shows what arrived and how long it took: sender to server, server to browser and end to end, with the average, fastest and slowest.

The frame of the event (channel, event name and the demo_from and demo_sent_at stamps) is fixed; your content goes into data. The demo uses a private channel of your own, is free on every plan, does not count towards your limits, allows 30 events a minute and deletes demo events after an hour.

Code examples

Replace the example key with your own public key (your API service shows these examples with your key filled in).

Web page: listen (and send)
<script src="https://pulse.devquake.com/api/v1/client"></script>
<script>
  var pulse = DevQuakePulse.connect({
    key: 'pk_YourPublicKeyFromTheApp00',
    channels: ['demo'],
    onEvent: function (e) { console.log(e.event, e.data); },
    onStatus: function (s) { console.log('pulse:', s); }
  });
  // Only when "Browsers may send events" is on:
  // pulse.send('demo', 'hello', { text: 'Hi' });
</script>
Your server: send an event
curl -X POST https://pulse.devquake.com/api/v1/events \
  -H "Authorization: Bearer $PULSE_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channel":"demo","event":"hello","data":{"text":"Hi","count":1}}'
Your server: a client token for private channels
// Your server (Node.js): a client token for one of your users, valid for one hour.
import { createHmac } from 'node:crypto';

const b64 = (o) => Buffer.from(JSON.stringify(o)).toString('base64url');

export function pulseToken(userId, channels, canSend) {
  const now = Math.floor(Date.now() / 1000);
  const head = b64({ alg: 'HS256', typ: 'JWT' }) + '.' + b64({
    app: 'pk_YourPublicKeyFromTheApp00', ch: channels, pub: canSend,
    sub: String(userId), iat: now, exp: now + 3600,
  });
  const sig = createHmac('sha256', process.env.PULSE_SECRET_KEY).update(head).digest('base64url');
  return head + '.' + sig;
}

// In the page: DevQuakePulse.connect({ token: () => fetch("/my/pulse-token").then((r) => r.text()), … })
What every listener receives
{
  "id": "812",
  "app": "pk_YourPublicKeyFromTheApp00",
  "channel": "orders",
  "event": "order.created",
  "data": {
    "orderId": "A-17",
    "total": 42.5,
    "paid": true
  },
  "source": "server",
  "at": "2026-09-26T10:00:00.000Z"
}

Questions or ideas? Write to contact@devquake.com.

← Back to Pulse