Skip to content
Documentation menuRequest signatures

Request signatures. Prove that server events come from your server.

Server sources sign every request with the signing secret (sk_…). With Signature required on the source, an unsigned or wrongly signed request is refused; whoever gets hold of the write key cannot send events in your server’s name.

The signature travels in Metrics-Signature: t=<unix seconds>,v1=<hex>. v1 = hex(HMAC-SHA256(signingSecret, t + "." + rawBody)): it is computed over the exact bytes sent.

Node.js, no dependencies · JavaScript
import { createHmac } from 'node:crypto';

const body = JSON.stringify({ userId: 'usr_7c1e', event: 'signup_completed', messageId: 'signup:7c1e' });
const t = Math.floor(Date.now() / 1000);
const v1 = createHmac('sha256', process.env.METRICS_SIGNING_SECRET).update(`${t}.${body}`).digest('hex');

await fetch('https://collect.<domain>/v1/track', {
  method: 'POST',
  headers: {
    authorization: `Basic ${Buffer.from(`${process.env.METRICS_WRITE_KEY}:`).toString('base64')}`,
    'content-type': 'application/json',
    'metrics-signature': `t=${t},v1=${v1}`,
  },
  body,
});

Rules

  • If t is more than ±300 s off the server clock, the request gets 401 signature_expired; keep your server clock synced with NTP.
  • While a secret is rotated, the header may carry several v1= values; the request is accepted if one is valid.
  • On a source that requires signatures, an unsigned request gets 401 signature_required, a wrong one 401 signature_invalid.
  • Segment clients cannot sign: use the Postlip Metrics SDK for sources that require signatures.
  • POST /v1/ping is signed over the body {} and answers with the state of the signature (valid or absent); it stores nothing.