Persons and events
Create and update persons, capture events, send push notifications and erase data from Node.js.
Node.js code for persons, events and push notifications, using a configured client.
Persons
Create a person
const person = await voidhash.persons.create({
payload: { distinctId: "user_123", email: "ada@example.com", name: "Ada" },
});
console.log(person.id); // person_…email and name can be null.
Find a person
list filters by distinct ID or email:
const { data } = await voidhash.persons.list({ params: { distinctId: "user_123" } });
const person = data[0]; // undefined when Voidhash has never seen user_123
const byEmail = await voidhash.persons.list({ params: { email: "ada@example.com" } });get rejects with person_not_found for an unknown or erased ID.
const person = await voidhash.persons.get({ params: { personId: "person_k2v9x4m8q1r3" } });listSubscriptions, listPurchases and listEntitlements take the same personId.
Update attributes
update sets attributes:
await voidhash.persons.update({
params: { personId: "person_k2v9x4m8q1r3" },
payload: {
traits: { plan: "team", seats: 5 },
setOnce: { signupSource: "website" },
},
});Capture events
eventCapture.capture takes timestamp as an ISO 8601 string.
Create the client with ingestUrl: "https://api.voidhash.com"; the default capture host doesn't
answer yet.
await voidhash.eventCapture.capture({
distinctId: "user_123",
event: "report_exported",
timestamp: new Date().toISOString(),
properties: { format: "csv", rows: 1200 },
});eventCapture.batch sends an array in one request; an empty array sends nothing.
const { accepted, rejected } = await voidhash.eventCapture.batch([
{ distinctId: "user_123", event: "trial_reminder_sent", timestamp: new Date().toISOString() },
{ distinctId: "user_456", event: "trial_reminder_sent", timestamp: new Date().toISOString() },
]);Errors carry an event capture code.
Send push notifications
Push notifications are in early access. Ask us on Discord, or email support@voidhash.com on a paid plan, to turn them on for your team.
Pass an idempotency-key so a retry returns the first send instead of notifying twice.
const sent = await voidhash.pushNotifications.create({
params: { "idempotency-key": "renewal-reminder-user_123-2026-11" },
payload: {
distinctIds: ["user_123"],
title: "Your trial ends tomorrow",
body: "Keep Pro for $9.99 a month.",
data: { screen: "paywall" },
},
});
console.log(sent.id, sent.deviceCount, sent.unresolvedDistinctIds);pushNotifications.listDeliveries({ params: { pushNotificationId: sent.id } }) follows delivery;
see Send a push.
Erase personal data
persons.createErasure takes exactly one of distinctId or personId and needs
project:persons:delete.
const erasure = await voidhash.persons.createErasure({ payload: { distinctId: "user_123" } });
const status = await voidhash.persons.getErasure({ params: { erasureId: erasure.id } });
console.log(status.status); // queued | in_progress | completed | failedDelete personal data explains what is kept.
The person's identity and attributes are gone for good. Purchases and revenue stay recorded against an anonymized person.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.