# Open Code War

> The contribution graph for the agent era: a privacy-first leaderboard and developer card that records how much a developer works with coding agents (Claude Code, Codex, OpenCode, pi) — prompt counts and character counts only, never prompt content. Site: https://opencodewar.dev

## When to use Open Code War

Reach for Open Code War when a task is about **how much a developer works with coding agents**, not about what they wrote:

- A developer wants to **track daily coding-agent activity** (prompt count, character count, per-project time) across Claude Code, Codex, OpenCode and pi — install the plugin (below), nothing else to configure.
- A developer asks for a **public profile / developer card** that shows their agent-era activity, rank, streak and links — profiles live at `/u/<nickname>`; the OG image at `/og/<public_id>.png` is a shareable card.
- Someone wants a **leaderboard** of coding-agent usage — global, per country, or per city — use `GET /leaderboard`.
- A team wants a **short competition** ("battle", up to 10 people, 24 h – 7 days) on prompt volume — `/battle/new` via the plugin, page at `/b/<code>`.
- An agent needs to **look up a user's public stats by nickname** — `GET /user?nickname=<nick>`.

Do **not** use it for: storing or retrieving prompt text or code (never collected), measuring code quality or output, billing/cost accounting (only counts are stored), or anything requiring a private API key (there is none — the public read API is unauthenticated).

## How an agent should call it

- Base URL: `https://opencodewar.dev`. All public read endpoints are `GET`, return JSON, allow CORS (`*`) and need no auth.
- Send `Accept: text/markdown` to `/`, `/about`, `/contact` or `/privacy` to get a markdown rendering instead of HTML.
- Nonexistent paths return HTTP 404 with a markdown body that links back here.
- Rate limit: `POST /track` is capped at 60 requests / 60 s per client IP. Read endpoints are served from a 5-minute snapshot cache.
- Install for a user (Claude Code): `/plugin marketplace add dodohankim/opencodewar` then `/plugin install open-code-war@opencodewar`. Codex: `codex plugin marketplace add dodohankim/opencodewar` + `codex plugin add open-code-war@opencodewar`. OpenCode / pi: npm package `open-code-war`.

## Docs

- [About](https://opencodewar.dev/about): what it is, how it works, who runs it
- [API reference](https://opencodewar.dev/docs/api): every public endpoint with parameters
- [OpenAPI spec](https://opencodewar.dev/openapi.json): OpenAPI 3.1, read endpoints
- [Privacy policy](https://opencodewar.dev/privacy): what is collected and how to delete it
- [Contact](https://opencodewar.dev/contact): email, GitHub issues, security reports
- [Source code](https://github.com/dodohankim/opencodewar): Cloudflare Worker backend, plugin, web — BUSL-1.1
- [npm package open-code-war](https://www.npmjs.com/package/open-code-war): OpenCode / pi adapter

## Optional

- [llms-full.txt](https://opencodewar.dev/llms-full.txt): all of the above in one file
- [Sitemap](https://opencodewar.dev/sitemap.xml)


---

# About Open Code War

Open Code War (OCW) is **the contribution graph for the agent era**. It records every day a developer works with a coding agent — Claude Code, Codex, OpenCode, pi — as prompt counts, character counts and per-project time, and turns that record into a rank, a streak, a shareable developer card and a public leaderboard at https://opencodewar.dev.

## How it works

1. A small plugin hooks the agent's prompt-submit event (`UserPromptSubmit` in Claude Code / Codex; an extension in OpenCode and pi).
2. On every submit it sends **only numbers** — an anonymous device id, the character count, the agent name, an optional project label — to a Cloudflare Worker. It is fail-open: a short timeout and fire-and-forget, so it never slows the agent.
3. The Worker stores daily aggregates in D1 (SQLite) and publishes a ranking snapshot every 5 minutes.
4. The web app renders the leaderboard, profiles (`/u/<nickname>`), a developer card image, ranks (a 12-step ladder driven by lifetime prompts), streaks (UTC days with ≥10 prompts and >500 characters) and battles (up to 10 people, 24 h – 7 d).

## Privacy stance

Prompt **content** is never collected — not by the plugin, not by the server. No code, file paths, IP storage or real names. The entire codebase is open source so the claim can be verified: https://github.com/dodohankim/opencodewar. Full policy: https://opencodewar.dev/privacy.

## Who runs it

Open Code War is an independent, open-source project built and operated from Seoul, South Korea by its maintainer (GitHub: dodohankim). It is not affiliated with Anthropic, OpenAI, OpenCode or pi. It is free to use; there is no paid tier. Source license: BUSL-1.1.

## Links

- Leaderboard: https://opencodewar.dev/
- Contact: https://opencodewar.dev/contact
- API reference: https://opencodewar.dev/docs/api · OpenAPI: https://opencodewar.dev/openapi.json
- Agent guide: https://opencodewar.dev/llms.txt
- Source: https://github.com/dodohankim/opencodewar · npm package `open-code-war`


---

# Open Code War API reference

Base URL `https://opencodewar.dev`. JSON over HTTPS, CORS `*`, no authentication for reads. Machine-readable spec: [https://opencodewar.dev/openapi.json](https://opencodewar.dev/openapi.json).
Writes (`/track`, `/register`, `/profile`, `/delete`, `/battle/*`) identify the caller by the anonymous `userId` the plugin generates on the device; they are documented for transparency, not as a public write API.

## Read endpoints

### GET /leaderboard
Ranking snapshot (rebuilt every 5 minutes).

| Query | Values | Default |
|---|---|---|
| `type` | `all` · `daily` · `weekly` · `weekend` · `monthly` | `daily` |
| `metric` | `prompts` · `chars` | `prompts` |
| `limit` | 1–500 | 100 |
| `scope` | `global` · `country` · `city` | `global` |
| `country` | ISO 3166-1 alpha-2 (with `scope=country`/`city`) | — |
| `city` | city name (with `scope=city`) | — |

Example: `curl "https://opencodewar.dev/leaderboard?type=all&metric=prompts&limit=10"`

### GET /user
Public profile + last-30-day daily usage. `?nickname=<registered nickname>` or `?id=<public_id>`. Never returns the secret `userId`.

### GET /user/hours
Hour-of-day histogram for one user. Same identifier query as `/user`, optional `day=YYYY-MM-DD`.

### GET /zones
Countries and cities that have registered users (for scope filters).

### GET /random
One random public profile (for discovery).

### GET /battle?code=<code>
Public state of a battle (members, period, standings).

### GET /health
`{ "ok": true }` liveness probe.

## Plugin endpoints (called by the installed plugin)

- `POST /track` — `{ userId, chars, agent, project? }`. Counts only; prompt text is never sent. 60 req/60 s per IP.
- `POST /register` — `{ userId, nickname }` set a display name (2–15 chars, letters/digits/Korean/underscore/space).
- `POST /profile` — `{ userId, bio?, role?, company?, city?, country?, links?, projects? }`.
- `POST /delete` — `{ userId }` erase everything for that id.
- `GET /briefing?userId=` — one-line session briefing shown in the terminal.
- `POST /battle/new` · `/battle/join` · `/battle/leave`, `GET /battle/mine` — battles (max 10 members, 24 h – 7 d).

## Pages

- `/u/<nickname>` — profile page (HTML; OG tags rewritten per user).
- `/og/<public_id>.png` — 1200×630 developer card image.
- `/b/<code>` — battle page.

## Errors

Every error is JSON `{ "error": "<snake_case_code>" }` with a 4xx/5xx status (`invalid_nickname`, `not_found`, `rate_limited`, …). Unknown paths return 404 with a markdown body unless the request has `Accept: application/json`.


---

# Contact Open Code War

- **General / partnership / press:** contact@opencodewar.dev
- **Privacy requests (access, deletion, complaints):** privacy@opencodewar.dev — see https://opencodewar.dev/privacy for the identity check we perform
- **Bugs & feature requests:** https://github.com/dodohankim/opencodewar/issues (public, preferred for anything technical)
- **Security reports:** email privacy@opencodewar.dev with "security" in the subject; please do not open a public issue for exploitable bugs
- **Maintainer:** dodohankim on GitHub · operated from Seoul, South Korea (KST, UTC+9)

We aim to answer email within 5 business days and privacy requests within the 10-day window required by Korean law. Deletion can also be done instantly and without contacting us: run `/ocw delete` in your agent, or `POST /delete` with your device id.

Open Code War has no phone line and no physical office open to the public; email and GitHub are the only official channels.


---

# Open Code War Privacy Policy (summary)

Full text (English and Korean, effective 2026-08-10): https://opencodewar.dev/privacy — this summary is for agents and is not a substitute for the full policy.

## What is collected
- Anonymous device id generated at install (random; not linked to a person unless Google is linked).
- Usage counts: number of prompt submits and their character counts, the agent name, a timestamp.
- Country (2-letter code) and IANA timezone derived by Cloudflare from the IP — the IP itself is not stored.
- Optional: a project label you chose, a nickname, bio/role/company/links you enter, and — if you link Google — your Google account id and email (private by default).

## What is never collected
Prompt content, code, file names or paths, IP addresses (transient only), real name, phone, postal address, anything from Google beyond id and email.

## Retention & deletion
Kept while the record exists. `/ocw delete` in the agent or `POST /delete` erases everything immediately. Email privacy@opencodewar.dev for requests that need a human.

## Processors
Cloudflare (Workers, D1, KV — hosting), Google (OAuth only when you link), a VPS rendering the developer-card image. No sale or sharing of personal data for advertising.

## Contact
privacy@opencodewar.dev · Korean users may also contact the Personal Information Infringement Report Center (privacy.kisa.or.kr, ☎118).
