Skip to content

Getting Started ​

Need a view counter for a GitHub README, blog, or personal site? Tally API gives you a hosted counter endpoint with no signup and no backend to manage. If you prefer, you can also deploy the same stack to your own Cloudflare account.

Why Tally API ​

Tally API started as a simpler replacement for a counter stack built around LeanCloud, MongoDB Atlas, and Moe Counter. When LeanCloud announced the end of its public service in January 2026, moving the storage layer onto Cloudflare — first KV, and now D1 — became the cleaner long-term option.

Unlike Moe Counter, Tally API also exposes JSON. You can keep the familiar SVG badge for Markdown, or build your own UI around the raw count.

URL Structure ​

The API follows this format:

text
https://tally.yuki.sh/hits/:id/:resource[.format]
  • :id is your namespace
  • :resource is the counter name inside that namespace

If you want to track visits to a GitHub README, you might use:

http
https://tally.yuki.sh/hits/github/readme

If you want to track a blog post, for example https://blog.yuki.sh/posts/976864126ca2, you could use:

http
https://tally.yuki.sh/hits/blog/976864126ca2

The public instance runs on a shared domain, so choose a namespace that is unlikely to collide with someone else's. A pattern like github@yourname works well, for example /hits/github@xueelf/readme.

If you would rather not rely on a shared service, follow the Deploy guide and run your own instance.

Read Counts as JSON ​

You can request JSON directly:

http
GET https://tally.yuki.sh/hits/docs/tally-api.json

The .json suffix is optional. If you omit it, the API still returns JSON by default. The response contains the total hit count:

typescript
type Response = {
  visit: number;
};

That makes Tally API easy to integrate into your own components. The box below is rendered from a live API request:

Loading...

Full component source:

vue
<script setup lang="ts">
import { onMounted, ref } from 'vue';

const API = 'https://tally.yuki.sh/hits/docs/tally-api';
const visit = ref<number | null>(null);
const isFailed = ref(false);

onMounted(async () => {
  try {
    const response = await fetch(API);

    if (!response.ok) {
      throw new Error('Request failed');
    }
    const data: { visit: number } = await response.json();

    visit.value = data.visit;
  } catch {
    isFailed.value = true;
  }
});
</script>

<template>
  <div class="count-card">
    <span v-if="isFailed">Failed to fetch count.</span>
    <span v-else-if="visit === null">Loading...</span>
    <span v-else>Total API Hits: {{ visit }}</span>
  </div>
</template>

<style scoped>
.count-card {
  padding: 20px 24px;
  border-radius: 8px;
  background-color: var(--vp-code-block-bg);
}
</style>

Embed as SVG ​

If all you need is a counter badge in Markdown, SVG is the simplest option:

md
![counter](https://tally.yuki.sh/hits/docs/tally-api.svg)

Preview:

counter

You can switch themes with a query parameter:

md
![counter](https://tally.yuki.sh/hits/docs/tally-api.svg?theme=miku)

For example:

counter

Tally API supports every Moe Counter theme, including moebooru, gelbooru, miku, and minecraft. See https://count.getloli.com for the full gallery.

If you want the image itself to be clickable, wrap it in a link:

md
[![counter](https://tally.yuki.sh/hits/docs/tally-api.svg)](https://github.com/xueelf/tally-api)

Next Steps ​

For request rules, response formats, and error cases, continue with API Reference.