Developers

Collect in a few lines and sign server events.

One npm package for browser, React and Node: @yourownmetric/sdk v0.3.1. Zero dependencies, around 12 KB gzipped with every plugin.

01

Install and initialise

terminal· shell
npm install @yourownmetric/sdk
analytics.ts· TypeScript
import { YOM } from '@yourownmetric/sdk'

YOM.init({
  apiKey: 'yom_pk_live_…',          // publishable key from your dashboard
  consent: { default: 'unknown' },  // cookieless until granted
  autoCapture: {
    pageviews: true,
    engagement: true,
    errors: true,
    performance: true,
    ecommerce: true,
  },
})

// Call from your consent banner / CMP
YOM.setConsent({ analytics: true, marketing: false })

Until setConsent grants analytics, the SDK keeps no persistent id and writes nothing to storage. DNT and Global Privacy Control are treated as denied unless you opt out of that behaviour. Batches go out as text/plain through sendBeacon on page hide, with a fetch(keepalive) fallback.

02

Track conversions the GA4 way

checkout.ts· TypeScript
// GA4-aligned ecommerce helpers
YOM.ecommerce.viewItem({ item_id: 'SKU-1', price: 20 })
YOM.ecommerce.addToCart({ item_id: 'SKU-1', price: 20 }, 2)
YOM.ecommerce.purchase({
  transaction_id: '1043',
  value: 212.0,
  currency: 'USD',
})

// Lead / form conversion: never put contact details in the browser event
YOM.lead('contact-form')

// Any custom event (snake_case, up to 64 chars)
YOM.track('trial_started', { plan: 'pro' })

Event names follow the GA4 taxonomy, so existing GA4 events map across by name. purchase, refund, generate_lead, form_submit and sign_up are counted exactly and deduplicated on the event id.

03

React

App.tsx· React
import { YOMProvider, useTrack } from '@yourownmetric/sdk/react'

export function App() {
  return (
    <YOMProvider
      config={{ apiKey: 'yom_pk_live_…', consent: { default: 'unknown' }, autoCapture: { pageviews: true } }}
    >
      {/* your routes: page views are captured on every route change */}
    </YOMProvider>
  )
}

function BuyButton() {
  const track = useTrack()
  return <button onClick={() => track('cta_click', { id: 'buy' })}>Buy</button>
}

The React components need React 19.

04

Send conversions from your server

server.ts· Node
import { YOMServer } from '@yourownmetric/sdk/node'

const yom = new YOMServer({
  secretKey: process.env.YOM_SECRET_KEY,   // yom_sk_… with the server scope
  // auth: 'hmac', keyId: 'key_…',         // sign instead of sending the key
})

yom.track({
  event: 'purchase',
  id: '1043',                              // same id as the browser purchase = counted once
  subTenant: 'client-a',                   // optional: platforms & agencies
  params: { transaction_id: '1043', value: 212.0, currency: 'USD' },
})

// Lead details belong server-side, where they can reach your CRM
yom.track({ event: 'generate_lead', params: { form_id: 'demo', email } })

process.on('SIGTERM', async () => {
  await yom.shutdown()                     // flushes the queue
})

Server events keep the details you send (that’s how lead data reaches a CRM through your destinations), are batched per sub-tenant, retried with backoff, and carry stable ids so destinations can dedupe.

05

Or call the HTTP API directly

bearer auth· curl
curl -X POST https://ingest.yourownmetrics.aapastech.com/v2/events \
  -H "Authorization: Bearer $YOM_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "User-Agent: my-app/1.0" \
  -d '{
    "v": 2,
    "events": [{
      "e": "purchase",
      "id": "1043",
      "p": { "transaction_id": "1043", "value": 212.0, "currency": "USD" }
    }]
  }'
HMAC auth· shell
# HMAC instead of a bearer key: sign "<unix-ts>.<raw body>" with your secret key
BODY='{"v":2,"events":[{"e":"sign_up","id":"u-88"}]}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$YOM_SECRET_KEY" -hex | sed 's/^.* //')

curl -X POST https://ingest.yourownmetrics.aapastech.com/v2/events \
  -H "YOM-Key-Id: $YOM_KEY_ID" \
  -H "YOM-Signature: t=$TS,v1=$SIG" \
  -H "Content-Type: application/json" \
  -d "$BODY"

Up to 50 events or 64 KB per request. 429 and 5xx responses are safe to retry with the same ids. For HMAC, send the key’s id (key_…, shown next to the secret key in your dashboard and returned by the keys API) as YOM-Key-Id and sign with the secret key itself.

Calling from a script? Send your own User-Agent header, for example my-app/1.0. Our edge blocks some library defaults before they reach the API: Python’s urllib sends Python-urllib/3.x, which gets a Cloudflare 1010 error. With requests, pass headers={"User-Agent": "my-app/1.0"}; with urllib, set it on the request: urllib.request.Request(url, headers={"User-Agent": "my-app/1.0"}).

06

Verify signed webhooks

app/api/yom/route.ts· TypeScript
import { verifyWebhook } from '@yourownmetric/sdk/node'

export async function POST(req: Request) {
  const raw = await req.text()                       // the RAW body, before JSON.parse
  const ok = await verifyWebhook(
    process.env.YOM_WEBHOOK_SECRET,                  // whsec_… shown once at creation
    req.headers.get('yom-signature'),
    raw,
  )
  if (!ok) return new Response('bad signature', { status: 401 })

  const eventId = req.headers.get('yom-event-id')    // stable across retries
  // if (await seen(eventId)) return new Response('ok')  ← dedupe here
  const payload = JSON.parse(raw)
  return new Response('ok')
}

Not using the SDK? The signature is plain HMAC-SHA256:

verify.ts· Node
import { createHmac, timingSafeEqual } from 'node:crypto'

// YOM-Signature: t=<unix>,v1=<hex hmac_sha256(secret, t + "." + body)>
export function verify(secret: string, header: string, rawBody: string) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.trim().split('=')))
  const t = Number(parts.t)
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false   // 5-minute tolerance
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex')
  const given = Buffer.from(parts.v1 ?? '', 'hex')
  return given.length === 32 && timingSafeEqual(given, Buffer.from(expected, 'hex'))
}

Headers on every delivery

  • YOM-Signature: t=<unix>,v1=<hex>
  • YOM-Event-Id: <stable across retries>

Platforms can replace the YOM- prefix and user agent with their own brand. Failed deliveries retry for about 24 hours, with a delivery log and redelivery.

More for developers

  • MCP server: 13 read-only report tools over Streamable HTTP, Bearer read-scoped keyLive
  • Partner API: management keys create projects and mint keysLive
  • <yom-report> web component (@yourownmetric/embed) with embed tokensLive
  • Meta CAPI and GA4 Measurement Protocol destinations, consent-gatedLive
  • Warehouse exports: S3, GCS, R2, BigQuery; Snowflake via external stageLive
  • GA4 gtag shim (@yourownmetric/sdk/gtag-shim) and GA4 BigQuery importLive
  • WordPress and WooCommerce pluginEarly access
  • ShopifyComing soon
  • Looker Studio community connector (self-deploy)Early access
  • Google Ads Enhanced ConversionsComing soon

Start measuring

Get a key and send your first event.

Sign up free, create a project and copy the publishable key. You won’t need a credit card.