Appcheckly

Demo projectA design and product demo, not a live service. Nothing here is for sale and there are no accounts. About this demo

Setup

Set up Lumen Ledger

Send activity events so weeks can be confirmed.

App key

Your app key: app_demo_lumen

A sample key for the demo. The secret is shown once, when an app is created.

Moments to watch

budget_createdentry_addedweekly_review_opened

Integration snippet

// appcheckly.js — send activity events to Appcheckly. No dependencies.
// Set APPCHECKLY_APP_KEY and APPCHECKLY_INGEST_SECRET on your server.
const crypto = require('node:crypto');

const URL_BASE = 'https://ingest.example.invalid/';
const APP_KEY = process.env.APPCHECKLY_APP_KEY;
const SECRET = process.env.APPCHECKLY_INGEST_SECRET;

async function appcheckly(testerId, event, opts = {}) {
  if (!testerId || !APP_KEY || !SECRET) return;            // no tester id, nothing to send
  const payload = {
    tester_id: testerId,                                    // the code the tester pasted in
    event,                                                  // 'session_end' or one of your key events
    occurred_at: new Date(opts.occurredAt || Date.now()).toISOString(),
  };
  if (opts.sessionMs != null) payload.session_ms = Math.round(opts.sessionMs);
  if (opts.id) payload.id = String(opts.id);                // your own id makes retries safe
  if (opts.props) payload.props = opts.props;               // small flat object, strings/numbers/booleans

  const body = JSON.stringify(payload);
  if (Buffer.byteLength(body, 'utf8') > 1024) throw new Error('Appcheckly: event over 1 KB');

  const t = Math.floor(Date.now() / 1000);
  const v1 = crypto.createHmac('sha256', SECRET).update(`${t}.${body}`).digest('hex');

  const res = await fetch(URL_BASE + APP_KEY, {
    method: 'POST',
    headers: { 'content-type': 'application/json', 'appcheckly-signature': `t=${t},v1=${v1}` },
    body,
  });
  if (!res.ok) console.warn('Appcheckly ingest', res.status, await res.text());
  return res.ok;
}

// Send one session_end per session, with its real duration:
//   await appcheckly(user.appchecklyId, 'session_end', { sessionMs: Date.now() - session.startedAt });
// Send each moment you asked us to watch for, by its exact name:
//   await appcheckly(user.appchecklyId, 'plan_generated');
// Retries are safe: the same id is stored once.

module.exports = { appcheckly };

Test your integration

Sends one sample session_end event and shows the response.

{ "ok": true, "event": "session_end", "sample": true }