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 header and how it is computed
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
tis more than ±300 s off the server clock, the request gets401 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 one401 signature_invalid. - Segment clients cannot sign: use the Postlip Metrics SDK for sources that require signatures.
POST /v1/pingis signed over the body{}and answers with the state of the signature (validorabsent); it stores nothing.