Using Counters in Node.js
Send counter increments, decrements, and reads from a Node.js application using the TapTally HTTP API.
Overview
Every counter operation in TapTally is a plain HTTP request. This page shows how to fire increments, decrements, and reads from Node.js — no SDK required.
Prerequisites
- A TapTally instance with a known base URL (e.g.
http://localhost:8080) - An API key with at least
write:countersscope — see Counter API Keys for how to create one - A counter that already exists (namespace + key pair) — see Counters
API at a glance
POST /v1/counters/{namespace}/{key}/incr
POST /v1/counters/{namespace}/{key}/decr
GET /v1/counters/{namespace}/{key}The request body for increment/decrement is optional. Omit it to step by 1, or pass { "by": N } to step by any integer:
{ "by": 5 }Every response returns a counter object:
{
"namespace": "blog",
"key": "post-views",
"value": 42,
"updated_at": "2025-07-07T10:30:00Z"
}The X-API-Key header is required on every authenticated request.
Example
Uses the built-in fetch available in Node 18+. No extra dependencies needed.
const BASE_URL = process.env.TAPTALLY_URL ?? "http://localhost:8080";
const API_KEY = process.env.TAPTALLY_API_KEY;
async function increment(namespace, key, by = 1) {
const res = await fetch(
`${BASE_URL}/v1/counters/${namespace}/${key}/incr`,
{
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ by }),
}
);
if (!res.ok) throw new Error(`TapTally increment failed: ${res.status}`);
return res.json();
}
async function decrement(namespace, key, by = 1) {
const res = await fetch(
`${BASE_URL}/v1/counters/${namespace}/${key}/decr`,
{
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ by }),
}
);
if (!res.ok) throw new Error(`TapTally decrement failed: ${res.status}`);
return res.json();
}
async function getCounter(namespace, key) {
const res = await fetch(
`${BASE_URL}/v1/counters/${namespace}/${key}`,
{ headers: { "X-API-Key": API_KEY } }
);
if (!res.ok) throw new Error(`TapTally read failed: ${res.status}`);
return res.json();
}
// Example usage
const counter = await increment("blog", "post-views");
console.log("New value:", counter.value);Error reference
| Status | Meaning |
|---|---|
401 |
Missing or invalid API key |
403 |
Key exists but lacks write:counters scope, or the key is scoped to a different counter |
404 |
Counter (namespace / key pair) does not exist — create it first via the UI or the API |
400 |
Malformed request body |
Check
res.okafter every request and throw early rather than silently dropping events.
Where to next
- Using Counters in Go — Go example
- Using Counters in Python — Python example
- Counter API Keys — create and scope API keys
- Dashboards & Analytics — visualise the data you are sending
Found an issue in the docs? Open an issue on GitHub.