DEV Community

Cover image for countapi.xyz is dead. Here's the drop-in replacement I found (and actually use)
Miles Hilliard
Miles Hilliard

Posted on

countapi.xyz is dead. Here's the drop-in replacement I found (and actually use)

If you've been using countapi.xyz for page view tracking, button click counters, or really anything that just needed a simple number that goes up... you've probably noticed it's gone. No announcement, no migration guide, just a dead URL.

And honestly, it was one of those APIs that was so useful precisely because it asked nothing of you. No account. No API key. No SDK to install. Just fetch a URL and get a number back. It was perfect.

So when it died, a lot of people were left hunting for alternatives. Most of what I found either required signing up, had weird rate limits buried in the fine print, or was just overkill for what is fundamentally a very simple problem.

Then I found countapi.mileshilliard.com and it's basically exactly what we lost.


What it is

It's a free, open source counting API built as a direct spiritual successor to countapi.xyz. No signup. No API keys. No headers. You just hit an endpoint and it gives you a number.

The whole thing runs on a Python serverless backend with Redis, and it's hosted on OCI with near 99% uptime (there's a public UptimeRobot dashboard you can check yourself).

The concept is dead simple: every counter is identified by a unique key. That's it. You pick a key name, and the API tracks a number against it. Since there are no namespaces like the original had, you just want to make your key specific enough that nobody else is going to accidentally share it, something like johns-blog-homepage-visits rather than just visits.


The endpoints

There are really only three you'll ever use:

Hit (increment by +1)

GET /api/v1/hit/your_key
Enter fullscreen mode Exit fullscreen mode
{
  "key": "your_key",
  "message": "Key updated successfully",
  "value": "42"
}
Enter fullscreen mode Exit fullscreen mode

Get (read without incrementing)

GET /api/v1/get/your_key
Enter fullscreen mode Exit fullscreen mode
{
  "key": "your_key",
  "message": "Key requested successfully",
  "value": "42"
}
Enter fullscreen mode Exit fullscreen mode

Set (jump to a specific value)

GET /api/v1/set/your_key?value=100
Enter fullscreen mode Exit fullscreen mode
{
  "key": "your_key",
  "message": "Key set successfully",
  "old_value": "42",
  "value": "100"
}
Enter fullscreen mode Exit fullscreen mode

That's the whole API. There's also /api/v1/status and /health if you want to ping it for monitoring purposes.


Using it in practice

Adding a page view counter to any site is maybe 5 lines of JavaScript:

<p>This page has been visited <span id="visits">...</span> times.</p>

<script>
  fetch('https://countapi.mileshilliard.com/api/v1/hit/my-site-homepage')
    .then(res => res.json())
    .then(data => {
      document.getElementById('visits').textContent = data.value;
    });
</script>
Enter fullscreen mode Exit fullscreen mode

If you're on a platform that doesn't allow JavaScript at all (like certain Notion pages or some README renderers), there's even a tracking pixel approach:

<img src="https://countapi.mileshilliard.com/api/v1/hit/my-site-visits" style="display:none;" alt="" />
Enter fullscreen mode Exit fullscreen mode

No JS required. The hit happens server-side when the image loads.


Migrating from countapi.xyz

If you were using countapi.xyz, your old calls probably looked like this:

fetch('https://api.countapi.xyz/hit/mysite.com/visits')
Enter fullscreen mode Exit fullscreen mode

The new equivalent is:

fetch('https://countapi.mileshilliard.com/api/v1/hit/mysite-visits')
Enter fullscreen mode Exit fullscreen mode

The main difference is there are no namespaces anymore, so you fold your old namespace and key together into one unique key. Everything else works the same way.


A few things worth knowing

All keys are public. Anyone who knows your key name can read or hit your counter. This is by design and is the tradeoff for having zero auth overhead. Just don't use it to store anything sensitive (not that a number really could be, but still).

Keys don't expire. If you want to "reset" a counter, use the /set endpoint or just start using a new key name.

There is rate limiting, though the docs describe it as "extremely generous." Someone apparently stress tested it without warning, which is how rate limiting got added in the first place. The docs have a great line about this: "Shoot me an email before you try to... if you wouldn't mind."

It's open source. The whole thing is on GitHub at syntaxerror019/countapi if you want to self-host or contribute.


Why I like it

There are absolutely fancier analytics tools out there. But sometimes you really do just want a number that goes up. This API gets that. It doesn't ask you to create an account to track 12 page views on your personal blog. It doesn't require you to read 40 pages of docs. It just works.

The fact that it's a community project filling a gap that a commercial service left behind makes it even better. If you end up using it, maybe give the repo a star or drop the maintainer a note. Small projects like this run on that kind of encouragement.


Links:

Top comments (0)